Occasionally, you may want to create multiple windows in an application. The application opens a new window to perform the specified task. The new windows are called subwindows, and the main frame is called the main window .
To create a subwindow from an application, you need to create a subclass of JFrame that defines the task and tells the new window what to do. You can then create an instance of this subclass in the application and launch the new window by setting the frame instance to be visible.
Listing 15.11 gives a program that creates a main window with a text area in the scroll pane and a button named "Show Histogram." When the user clicks the button, a new window appears that displays a histogram to show the occurrences of the letters in the text area. Figure 15.31 contains a sample run of the program.
Here are the major steps in the program:
1. | Create a main class for the frame named MultipleWindowsDemo in Listing 15.11. Add a text area inside a scroll pane, and place the scroll pane in the center of the frame. Create a button "Show Histogram" and place it in the south of the frame. |
| |
2. | Create a subclass of JPanel named Histogram in Listing 15.12. The class contains a data field named count of the int[] type, which counts the occurrences of twenty-six letters. The values in count are displayed in the histogram. |
3. | Implement the actionPerformed handler in MultipleWindowsDemo , as follows :
|
1 import java.awt.*; 2 import java.awt.event.*; 3 import javax.swing.*; 4 5 public class MultipleWindowsDemo extends JFrame { 6 private JTextArea jta; 7 private JButton jbtShowHistogram = new JButton( "Show Histogram" ); 8 private Histogram histogram = new Histogram(); 9 10 // Create a new frame to hold the histogram panel 11 private JFrame histogramFrame = new JFrame(); 12 13 public MultipleWindowsDemo() { 14 // Store text area in a scroll pane 15 JScrollPane scrollPane = new JScrollPane(jta = new JTextArea()); 16 scrollPane.setPreferredSize(new Dimension( 300 , 200 )); 17 jta.setWrapStyleWord( true ); 18 jta.setLineWrap( true ); 19 20 // Place scroll pane and button in the frame 21 add(scrollPane, BorderLayout.CENTER); 22 add(jbtShowHistogram, BorderLayout.SOUTH); 23 24 // Register listener 25 jbtShowHistogram.addActionListener( new ActionListener() { 26 /** Handle the button action */ 27 public void actionPerformed(ActionEvent e) { 28 // Count the letters in the text area 29 int [] count = countLetters(); 30 31 // Set the letter count to histogram for display 32 histogram.showHistogram(count); 33 34 // Show the frame 35 histogramFrame.setVisible( true ); 36 } 37 }); 38 39 // Create a new frame to hold the histogram panel 40 histogramFrame.add(histogram); 41 histogramFrame.pack(); 42 histogramFrame.setTitle( "Histogram" ); 43 } 44 45 /** Count the letters in the text area */ 46 private int [] countLetters() { 47 // Count for 26 letters 48 int [] count = new int [ 26 ]; 49 50 // Get contents from the text area 51 String text = jta.getText(); 52 53 // Count occurrence of each letter (case insensitive) 54 for ( int i = ; i < text.length(); i++) { 55 char character = text.charAt(i); 56 57 if ((character >= 'A' ) && (character <= 'Z' )) { 58 count[( int )character - 65 ]++; // The ASCII for 'A' is 65 59 } 60 else if ((character >= 'a' ) && (character <= 'z' )) { 61 count[( int )character - 97 ]++; // The ASCII for 'a' is 97 62 } 63 } 64 65 return count; // Return the count array 66 } 67 68 public static void main(String[] args) { 69 MultipleWindowsDemo frame = new MultipleWindowsDemo(); 70 frame.setLocationRelativeTo( null ); // Center the frame 71 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 72 frame.setTitle( "MultipleWindowsDemo" ); 73 frame.pack(); 74 frame.setVisible( true ); 75 } 76 } |
1 import javax.swing.*; 2 import java.awt.*; 3 4 public class Histogram extends JPanel { 5 // Count the occurrence of 26 letters 6 private int [] count; 7 8 /** Set the count and display histogram */ 9 public void showHistogram( int [] count) { 10 this .count = count; 11 repaint(); 12 } 13 14 /** Paint the histogram */ 15 protected void paintComponent(Graphics g) { 16 if (count == null ) return ; // No display if count is null 17 18 super .paintComponent(g); 19 20 // Find the panel size and bar width and interval dynamically 21 int width = getWidth(); 22 int height = getHeight(); 23 int interval = (width - 40 ) / count.length; 24 int individualWidth = ( int )(((width - 40 ) / 24 ) * . 60 ); 25 26 // Find the maximum count. The maximum count has the highest bar 27 int maxCount = ; 28 for ( int i = ; i < count.length; i++) { 29 if (maxCount < count[i]) 30 maxCount = count[i]; 31 } 32 33 // x is the start position for the first bar in the histogram 34 int x = 30 ; 35 36 // Draw a horizontal base line 37 g.drawLine( 10 , height - 45 , width - 10 , height - 45 ); 38 for ( int i = ; i < count.length; i++) { 39 // Find the bar height 40 int barHeight = 41 ( int )((( double )count[i] / ( double )maxCount) * (height - 55 )); 42 43 // Display a bar (i.e., rectangle) 44 g.drawRect(x, height - 45 - barHeight, individualWidth, 45 barHeight); 46 47 // Display a letter under the base line 48 g.drawString(( char )( 65 + i) + " " , x, height - 30 ); 49 50 // Move x for displaying the next character 51 x += interval; 52 } 53 } 54 55 /** Override getPreferredSize */ 56 public Dimension getPreferredSize() { 57 return new Dimension( 300 , 300 ); 58 } 59 } |
The program contains two classes: MultipleWindowsDemo and Histogram . Their relationship is shown in Figure 15.32.
MultipleWindowsDemo is a frame that holds a text area in a scroll pane and a button. Histogram is a subclass of JPanel that displays a histogram for the occurrences of letters in the text area.
When the user clicks the "Show Histogram" button, the handler counts the occurrences of letters in the text area. Letters are counted regardless of their case. Nonletter characters are not counted. The count is stored in an int array of twenty-six elements. The first element stores the count for letter ' a' or ' A ,' and the last element in the array stores the count for letter ' z' or ' Z .' The count array is passed to the histogram for display.
The MultipleWindowsDemo class contains a main method. The main method creates an instance of MultipleWindowsDemo and displays the frame. The MultipleWindowsDemo class also contains an instance of JFrame , named histogramFrame , which holds an instance of Histogram . When the user clicks the "Show Histogram" button, histogramFrame is set visible to display the histogram.
The height and width of the bars in the histogram are determined dynamically according to the window size of the histogram.
You cannot add an instance of JFrame to a container. For example, adding histogramFrame to the main frame would cause a runtime exception. However, you can create a frame instance and set it visible to launch a new window.