13

In the following, I'm using user-defined macros to set the type style for the nodeparts for class nodes (\texttt{\textbf{#1}}), interfaces (\texttt{\textit{#1}}).

Using the \tikzset command I also define styles for classes or interfaces that define how these node parts shoulde be aligned and filled. Is there a correct way to set the typesetyle of the node parts as well?

\documentclass{beamer}

\usepackage{tikz}
\usetikzlibrary{shapes}
\usetikzlibrary{arrows}
\usetikzlibrary{calc}  

\usepackage{aeguill}
\newcommand*{\stereotype}[1]{
    \guillemotleft {#1}\guillemotright%
}                                      

\tikzset{class or interface/.style={%
           draw,%                    
           shape=rectangle split,%   
           rectangle split parts=3,% 
           rectangle split part align={center,left,left},%
           rectangle split part fill={#1!30!white,#1!20!white,#1!10!white}},
         interface/.style={class or interface=green},                       
         concrete class/.style={class or interface=red}}                    
\newtheorem{exercise}{Exercise}                                             

\newcommand*\umlClassStyle[1]{\texttt{\textbf{#1}}}
\newcommand*\umlAbstractClassStyle[1]{\texttt{\textit{#1}}}
\newcommand*\umlInterfaceStyle[1]{\texttt{\textit{#1}}}    

\begin{document}

%
%
\begin{frame}[fragile]
   \frametitle{Class Diagram of the Observer Pattern}
   \begin{tikzpicture}[every text node part/.style={align=center}%
                      ,every two node part/.style={align=center}% 
                      ,every three node part/.style={align=left}% 
                      ,node distance=2]                              
      \path (0,0) node(Subject)[interface,anchor=east]               
                  {\nodepart{text}                                   
                     \stereotype{interface}\\                        
                     \umlInterfaceStyle{Subject}                     
                   \nodepart{two}                                    
                   \nodepart{three}\tabular{@{}l}                    
                     \texttt{attach( Observer o )}\\                 
                     \texttt{detach( Observer o )}\\                 
                     \texttt{notify( )}                              
                   \endtabular}                                      
            (Subject.south)                                          
           +(+0.0,-1.5)node(ConcreteSubject)[concrete class,anchor=north]
                  {\nodepart{text}                                       
                     \umlClassStyle{ConcreteSubject}                     
                   \nodepart{two}                                        
                     \texttt{Observer[] observers}                       
                   \nodepart{three}\tabular{@{}l}                        
                     \texttt{attach( Observer o )}\\                     
                     \texttt{detach( Observer o )}\\                     
                     \texttt{notify( )}                                  
                   \endtabular}                                          
            (Subject.north east)
           +(+1.5,+0.0)node(ConcreteObserver)[concrete class,anchor=north west]
                  {\nodepart{text}
                     \umlClassStyle{ConcreteObserver}
                   \nodepart{two}
                     \texttt{Subject subject}
                   \nodepart{three}
                     \texttt{update( Object o )} }
            (ConcreteObserver.south |- ConcreteSubject.north)
                  node(Observer)[interface,anchor=north]
                  {\nodepart{text}
                     \stereotype{interface} \\
                     \umlInterfaceStyle{Observer}
                   \nodepart{two}
                   \nodepart{three}
                     \texttt{update( Object o )} };
      \draw[->,>=open triangle 90,dashed]
           (ConcreteSubject) -- (Subject)
       node[pos=0.1,anchor=south east] {\scriptsize{implements}};
      \draw[->,>=open triangle 90,dashed]
           (ConcreteObserver) -- (Observer)
       node[pos=0.1,anchor=north east] {\scriptsize{implements}};
      \draw[<->,arrows=open diamond-angle 90]
           (ConcreteSubject.text east) -- (ConcreteSubject.text east -| Observer.west)
       node[pos=0.1,anchor=south west] {\scriptsize{has a}}
       node[very near end,anchor=south] {\scriptsize{$n$}};
      \draw[<->,arrows=open diamond-angle 90]
           (ConcreteObserver.text west) -- (ConcreteObserver.text west -| Subject.east)
       node[pos=0.1,anchor=south east] {\scriptsize{has a}}
       node[very near end,anchor=south] {\scriptsize{$1$}};
   \end{tikzpicture}
\end{frame}
%
%

\end{document}

observer patterns

  • I believe your first sentence is supposed to read "I'm using user-defined macros to set the type style for the nodeparts...". You might want to consider boiling down your example to include only the stuff that's necessary to illustrate the problem. As it is, it's quite complicated, and includes a package that's not necessary to demonstrate the issue (aeguill). – Jake Jan 23 '12 at 05:19
  • @Jake You are right about the first sentence. As to the example, I could make up one but I decided I might as well give some motivation and show why I need it. –  Jan 23 '12 at 05:23

2 Answers2

12

You can choose the font for a node part by using the normal TikZ key font=<font switch like \bfseries>. Note that the default Computer Modern font does not have a bold typewriter font. You can use the Courier font for that (see Using \ttfamily with \bfseries (or how to enable bold in fixed-width font)).

\documentclass{beamer}

\usepackage{tikz}
\usetikzlibrary{shapes}
\usetikzlibrary{arrows}
\usetikzlibrary{calc}  




\usepackage{aeguill}
\newcommand*{\stereotype}[1]{
    \guillemotleft {#1}\guillemotright%
}                                      

\tikzset{class or interface/.style={%
        draw,%                    
        shape=rectangle split,%   
        rectangle split parts=3,% 
        rectangle split part align={center,left,left},%
        rectangle split part fill={#1!30!white,#1!20!white,#1!10!white},
        every two node part/.style={align=center, font=\ttfamily},
                     every three node part/.style={align=left, font=\ttfamily}, 
                     node distance=2
    },
         interface/.style={
        class or interface=green,
        every one node part/.style={align=center, font=\ttfamily\itshape}
    },                       
         concrete class/.style={
        class or interface=red,
        every one node part/.style={align=center, font=\ttfamily\bfseries}
    }
}                    
\newtheorem{exercise}{Exercise}                                             


\begin{document}
\renewcommand{\ttdefault}{pcr} % Choose typewriter font that supports bold
%
%
\begin{frame}[fragile]
   \frametitle{Class Diagram of the Observer Pattern}
   \begin{tikzpicture}]                              
      \path (0,0) node(Subject)[interface,anchor=east]               
                  {\nodepart{one}                                   
                     \stereotype{interface}\\                        
                     Subject                     
                   \nodepart{two}                                    
                   \nodepart{three}\tabular{@{}l}                    
                     attach( Observer o )\\                 
                     detach( Observer o )\\                 
                     notify( )                              
                   \endtabular}                                      
            (Subject.south)                                          
           +(+0.0,-1.5)node(ConcreteSubject)[concrete class,anchor=north]
                  {\nodepart{one}                                       
                     ConcreteSubject
                   \nodepart{two}                                        
                    Observer[] observers
                   \nodepart{three}\tabular{@{}l}                        
                     attach( Observer o )\\                     
                     detach( Observer o )\\                     
                     notify( )                     
                   \endtabular};
   \end{tikzpicture}
\end{frame}
%
%

\end{document}
Jake
  • 232,450
1

Bases on very interesting Jake answer but with some effort to make code more concise (used recent Beamer v3.41 and Tikz v 3.0.1a):

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{arrows, calc, positioning, shapes}% added positioning
\usepackage{aeguill}% for defining of quotation marks
\newcommand*{\stereotype}[1]{
    \guillemotleft {#1}\guillemotright%
                            }
\renewcommand{\ttdefault}{pcr} % Choose typewriter font that supports bold face
\tikzset{
box/.style={% simplified
        draw,
        shape=rectangle split,
        rectangle split parts=3,
        align=center,
        rectangle split part fill={#1!30!white,#1!20!white,#1!10!white},
        font=\ttfamily,
        every three node part/.style={align=left}
            },
        node distance=1
        }% end of tikzset

\begin{document}
%
\begin{frame}
\frametitle{Class Diagram of the Observer Pattern}
\centering
   \begin{tikzpicture}
\node (Subject)         [box=green] {%
    \nodepart{one}\itshape  \stereotype{interface}\\
                            Subject
    \nodepart{two}
    \nodepart{three}        attach( Observer o )\\
                            detach( Observer o )\\
                            notify( )
                                    };
\node (ConcreteSubject) [box=red,below=of Subject]   {%
    \nodepart{one}\bfseries ConcreteSubject
    \nodepart{two}          Observer[] observers
    \nodepart{three}        attach( Observer o )\\
                            detach( Observer o )\\
                            notify( )
                                    };
   \end{tikzpicture}
\end{frame}
%
\end{document}

enter image description here

Zarko
  • 296,517