Java Swing phần 5 ppsx

99 372 0
Java Swing phần 5 ppsx

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Java Swing – O’Reilly - 397 - Adds a separator to the toolbar. Be sure not to confuse the toolbar separator with JSeparator, which is a separate Swing component. The toolbar separator created by this method is simply a blank area of space used to provide spacing between groups of toolbar components. The size is normally up to the toolbar, though you can specify the separator's size explicitly if you wish. protected void paintBorder(Graphics g) Overrides the paintBorder() method in JComponent in order to observe the borderPainted property. protected PropertyChangeListener createActionChangeListener(JButton b) An internal utility method that creates an individual property change listener for a specific menu item. The programmer typically will not need to call this method. protected void addImpl(Component comp, Object constraints, int index) Adds the given component to the toolbar, with the specified constraints, and at the position specified by index. 14.8.1.7 Creating a Toolbar The following example adds a toolbar to the JMenu example above, creating a set of buttons from the Action objects we added to the menu. Just for fun, we added tool tips to the buttons on the toolbar. We also allow the user to choose from a specified font combo box, showing that you can use other kinds of components in a toolbar. Note that we add the combo box and a JLabel for the combo box as separate components, and that the combo box uses its own actionPerformed() method: // ToolBarExample.java // import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.*; import javax.swing.event.*; public class ToolBarExample extends JPanel implements ActionListener { public JTextPane pane; public JMenuBar menuBar; public JToolBar toolBar; String fonts[] = {"Serif","SansSerif","Monospaced","Dialog","DialogInput"}; public ToolBarExample() { super(true); menuBar = new JMenuBar(); JMenu formatMenu = new JMenu("Justify"); formatMenu.setMnemonic('J'); Java Swing – O’Reilly - 398 - MenuAction leftJustifyAction = new MenuAction("Left", new ImageIcon("left.gif")); MenuAction rightJustifyAction = new MenuAction("Right", new ImageIcon("right.gif")); MenuAction centerJustifyAction = new MenuAction("Center", new ImageIcon("center.gif")); MenuAction fullJustifyAction = new MenuAction("Full", new ImageIcon("full.gif")); JMenuItem item; item = formatMenu.add(leftJustifyAction); item.setIcon((Icon)leftJustifyAction.getValue(Action.SMALL_ICON)); item.setHorizontalTextPosition(JMenuItem.RIGHT); item.setMnemonic('L'); item = formatMenu.add(rightJustifyAction); item.setIcon((Icon)rightJustifyAction.getValue(Action.SMALL_ICON)); item.setHorizontalTextPosition(JMenuItem.RIGHT); item.setMnemonic('R'); item = formatMenu.add(centerJustifyAction); item.setIcon((Icon)centerJustifyAction.getValue(Action.SMALL_ICON)); item.setHorizontalTextPosition(JMenuItem.RIGHT); item.setMnemonic('C'); item = formatMenu.add(fullJustifyAction); item.setIcon((Icon)fullJustifyAction.getValue(Action.SMALL_ICON)); item.setHorizontalTextPosition(JMenuItem.RIGHT); item.setMnemonic('F'); menuBar.add(formatMenu); menuBar.setBorder(new BevelBorder(BevelBorder.RAISED)); toolBar = new JToolBar(); JButton button; button = toolBar.add(leftJustifyAction); button.setActionCommand((String)leftJustifyAction.getValue(Action.NAME)); button.setToolTipText((String)leftJustifyAction.getValue(Action.NAME)); button = toolBar.add(rightJustifyAction); button.setActionCommand((String)rightJustifyAction.getValue(Action.NAME)); button.setToolTipText((String)rightJustifyAction.getValue(Action.NAME)); button = toolBar.add(centerJustifyAction); button.setActionCommand((String)centerJustifyAction.getValue(Action.NAME)); button.setToolTipText((String)centerJustifyAction.getValue(Action.NAME)); button = toolBar.add(fullJustifyAction); button.setActionCommand((String)fullJustifyAction.getValue(Action.NAME)); button.setToolTipText((String)fullJustifyAction.getValue(Action.NAME)); toolBar.addSeparator(); JLabel label = new JLabel("Font"); toolBar.add(label); toolBar.addSeparator(); JComboBox combo = new JComboBox(fonts); combo.addActionListener(this); toolBar.add(combo); // Disable one of the Actions fullJustifyAction.setEnabled(false); } public void actionPerformed(ActionEvent e) { try { pane.getStyledDocument().insertString(0, "Font ["+((JComboBox)e.getSource()).getSelectedItem()+ Java Swing – O’Reilly - 399 - "] chosen!\n", null); } catch (Exception ex) {;} } public static void main(String s[]) { ToolBarExample example = new ToolBarExample(); example.pane = new JTextPane(); example.pane.setPreferredSize(new Dimension(250, 250)); example.pane.setBorder(new BevelBorder(BevelBorder.LOWERED)); example.toolBar.setMaximumSize(example.toolBar.getSize()); JFrame frame = new JFrame("Menu Example"); frame.addWindowListener(new BasicWindowMonitor()); frame.setJMenuBar(example.menuBar); frame.getContentPane().add(example.toolBar, BorderLayout.NORTH); frame.getContentPane().add(example.pane, BorderLayout.CENTER); frame.pack(); frame.setVisible(true); } class MenuAction extends AbstractAction { public MenuAction(String text, Icon icon) { super(text, icon); } public void actionPerformed(ActionEvent e) { try { pane.getStyledDocument().insertString(0, "Action ["+e.getActionCommand()+"] performed!\n", null); } catch (Exception ex) {;} } } } This demonstrates one of the nice things about using Action objects. Not only can you populate a toolbar with buttons generated from Action icons, but you can also disable the Action directly with one method call. For example, ToolBarExample.java includes the line: fullJustifyAction.setEnabled(false); Once the action is disabled, all the triggering components are notified of the property change. In our program, both the menu item and the toolbar button for left justification are grayed, as shown in Figure 14.22 . Figure 14.22. Disabling actions automatically grays the toolbar and menu representations Java Swing – O’Reilly - 400 - As we mentioned, this program added a combobox to the toolbar as well. The layout of the combo box was not quite what was expected— Swing placed it towards the top of the toolbar, instead of in the middle. This is primarily an artifact of the layout used with the toolbar, the BoxLayout. You can override this layout manually (GridBagLayout() works effectively), but it is best to set the floatable property to false when you do so. Otherwise, the layout manager resets itself when the toolbar is repositioned. You can define the alignment of the components in the toolbar by setting the alignmentY (or alignmentX) property on each component you add. For example, adding the following lines to the previous example causes everything to line up nicely: label.setAlignmentY(0); combo.setAlignmentY(0); Finally, a JToolBar is a regular Swing component, so you can use more than one in an application. Again, if you do so, and you wish to make the toolbars floatable, it is best to place each toolbar in a concentric BorderLayout container, leaving the other three sides unpopulated. This will ensure that the toolbars maintain their respective positions if they are both dragged to a new side. 14.8.1.8 The MetalToolBarUI isRollover property The MetalLookAndFeel checks for a special client property called "JToolBar.isRollover" when it installs the MetalToolBarUI. If the value of this property is set to Boolean.TRUE, the UI installs a special dynamic border on any JButtons in the toolbar. This custom border only paints itself when the cursor is over the button; otherwise, the border is invisible. This gives a nice highlighting effect to the toolbar. If you are using the Metal L&F, you can turn this feature on by calling: MyToolbar.setClientProperty("JToolbar.isRollover", Boolean.TRUE); The other Swing L&Fs ignore this property. Chapter 15. Tables Java Swing – O’Reilly - 401 - Tables represent one of the most common formats for viewing data. Database records are easy to sort and choose from a table. Statistics on disk usage can be displayed for several computers or several time periods all at once. Stock market quotes can be tracked. And where would sales presentations be without tables? Well, the JTable class in the Swing package now gives you access to a single component that can handle all of the preceding examples and more. Without getting fancy, you can think of tables as an obvious expression of two-dimensional data. In fact, the JTable class has a constructor that takes an Object[][] argument and displays the contents of that two-dimensional array as a table with rows and columns. For example, Figure 15.1 shows how a table of string objects falls out very quickly. Figure 15.1. Two-dimensional array of strings for data This program was generated with very little code. All we did was set up a JTable object with an String[][] argument for the table data, and a String[] argument for the table's headers. Rather than adding the table itself directly to our window, we enclose it in a scroll pane: // SimpleTable.java // A test of the JTable class using default table models and a convenience // constructor. // import java.awt.*; import javax.swing.*; public class SimpleTable extends JFrame { public SimpleTable() { super("Simple JTable Test"); setSize(300, 200); addWindowListener(new BasicWindowMonitor()); JTable jt = new JTable(new String[][] { {"This", "is"}, {"a", "Test"}}, new String[] {"Column", "Header"}); JScrollPane jsp = new JScrollPane(jt); getContentPane().add(jsp, BorderLayout.CENTER); } public static void main(String args[]) { SimpleTable st = new SimpleTable(); st.setVisible(true); } } As you can see, we rely entirely on the data models built for us and simply pass in our data (a String[][] object) and our column headers (a String[] object). JTable takes care of the rest of it. With the default models, you can select multiple rows, edit individual cells, and listen for selection events. But of course, you are not restricted to the default models, and you can produce Java Swing – O’Reilly - 402 - some pretty interesting effects if you decide to roll your own. To get there, you need to know about the basics of a JTable, beginning with columns. 15.1 Table Columns With Swing tables, the basic unit is not an individual cell; rather, it is a column. Most columns in real-world tables represent a certain type that will be consistent for all of the records displayed. For example, a record containing a person's name will have a String type and might be the first column of the table. For every other record (row), the first cell is always a String. The columns do not need to all have the same type. The same record could hold not only a person's name, but whether or not they owned a computer. That column would hold boolean values, not String values. The ability to store different types of data also affects how the table draws the data. The table column that maps to the "owns a computer" field could use a JCheckBox object for the cells of this column, while using regular JLabel objects for the cells of other columns. But again, each column will have one data type and one class responsible for drawing it. Now, as the JTable class evolves, you may find alternate ways to think about tables without relying so heavily on columns. You'll want to keep an eye on the API in future releases of the JFC package. Figure 15.2 shows how the classes of the JTable package fit together. Figure 15.2. The JTable and related classes and interfaces 15.1.1 The TableColumn Class The starting point for building your columns is this class. The TableColumn class supplies access to all the basic components of an individual column. But, this class should not be confused with the TableColumnModel interface. That model, discussed in the next section, dictates the form of a collection of table columns, which then makes up a full table. Java Swing – O’Reilly - 403 - 15.1.1.1 Properties The TableColumn class has the properties listed in Table 15.1. Table 15.1, TableColumn Properties Property Data Type get is set bound Default Value cellEditor TableCellEditor null cellRenderer TableCellRenderer null headerRenderer TableCellRenderer null headerValue Object null identifier Object null maxWidth int Integer.MAX_VALUE minWidth int 15 modelIndex int 0 resizable boolean true width int 75 The cellEditor , cellRenderer, and headerRenderer properties determine which components are used to draw (and possibly edit) cell values. The default value of null for these properties indicates that a default renderer or editor should be built and used. The headerValue property is accessible to the headerRenderer for drawing an appropriate header. The identifier property is used to identify a column uniquely. If identifier is not specified, the getIdentifier() method returns the current headerValue. The minWidth and maxWidth properties determine the minimum and maximum width in pixels for the column. By setting these properties to the same value, you can create a fixed-width column. The current width of the column is stored in the width property. The modelIndex determines the index value used when rendering or editing the column to get the appropriate data values. It is normally set in the constructor, and does not need to be modified after that. Relocating the column on-screen has no effect on the model index. The resizable property only affects the user's ability to manually resize columns—you can programmatically resize a column at any time. 15.1.1.2 Constants Four of the properties are associated with constants that describe them, for use with property change events. These constants are listed in Table 15.2. Table 15.2, TableColumn Constants Constant Type Description CELL_RENDERER_PROPERTY String The property name of the cellRenderer property COLUMN_WIDTH_PROPERTY String The property name of the columnWidth property HEADER_RENDERER_PROPERTY String The property name of the headerRenderer property HEADER_VALUE_PROPERTY String The property name of the headerValue property 15.1.1.3 Events Java Swing – O’Reilly - 404 - The only events generated by the TableColumn class are property change events generated when any of the column's bound properties (cellRenderer, headerRenderer, headerValue, and width) are changed. public void addPropertyChangeListener(PropertyChangeListener l) public void removePropertyChangeListener (PropertyChangeListener l) Add or remove a property change listener interested in receiving events from this column. 15.1.1.4 Fields protected TableCellEditor cellEditor protected TableCellRenderer cellRenderer protected TableCellRenderer headerRenderer protected Object headerValue protected Object identifier protected boolean isResizable protected int maxWidth protected int minWidth protected int modelIndex protected int resizedPostingDisableCount protected int width The fields in the TableColumn class store their respective properties from Table 15.1. (The isResizable field corresponds to the resizable property.) 15.1.1.5 Constructors The following constructors exist for building TableColumn objects: public TableColumn() Creates an empty column with the default property values. public TableColumn(int modelIndex) Creates an empty column with the specified modelIndex. public TableColumn(int modelIndex, int width) Creates an empty column with the specified modelIndex and width in pixels. The minWidth and maxWidth properties keep their default values. public TableColumn(int modelIndex, int width, TableCellRenderer cellRenderer, TableCellEditor cellEditor) This constructor creates an empty column with the specified modelIndex, width in pixels, cellRenderer, and cellEditor. Either (or both) of the renderer or editor arguments can be null, in which case the appropriate default will be used. 15.1.1.6 Miscellaneous Methods Java Swing – O’Reilly - 405 - While the get/set methods for the properties constitute a majority of the TableColumn class, the following methods provide some additional functionality: protected TableCellRenderer createDefaultHeaderRenderer() Creates a TableCellRenderer object using an anonymous inner class to create a JLabel with a distinct border and background that reflects the fact that this is a header cell, and not a regular part of the table data. public void disableResizedPosting() public void enableResizedPosting() Increment and decrement a counter to determine whether or not column resize events are reported during or after a resize. A counter is used so that if two calls to disable the resize posting are received (presumably from two separate sources), two complementary enable calls must be received before resize posting is re-enabled. These methods are not commonly used. public void sizeWidthToFit() Forces the width of the column to match that of its header, even if it means modifying the minWidth or maxWidth properties. 15.1.2 The TableColumnModel Interface A single column is not a very interesting table—an interesting list, maybe, but not a table. To handle real tables (even ones with only one column) we need a model for storing several columns as a collection. The TableColumnModel interface provides that functionality in the Swing package. As you may have noticed from Figure 15.2, the JTable class uses a column model in addition to a table model. While the table model provides the specific values for the cells in a column, the column model provides information such as the column margins and whether or not column selections are allowed. The purpose of the TableColumnModel interface falls into two areas: managing column selections and column spacing. For managing selections, you have access to the usual selection properties, such as the number of selected columns and the selection model in place. For dealing with column spacing, you can control the column margins and view the total column width. 15.1.2.1 Properties TableColumnModel has the properties listed in Table 15.3. The columnCount property returns the number of columns supported by this model. While this might seem like redundant information, given that table model (discussed later in this chapter) knows how many columns it supports, the next chapter examines some column models that do not use all of the columns available in the table model. The columnMargin property dictates how much space should be left between columns. That spacing is included when calculating the value of the totalColumnWidth . You can turn column selection on or off with the columnSelectionAllowed property. If column selections are allowed, you can then use the selectionModel , selectedColumns, and selectedColumnCount properties to work with the selections. As with other selections, you can use the selectionModel to programmatically affect the selected columns if needed. Java Swing – O’Reilly - 406 - The column and columns properties let you access the table's columns themselves. The index used as an argument to getColumn() refers to the column's index in the column model, which doesn't necessarily match the index of the column in the table model, or the order in which columns appear on the screen. Table 15.3, TableColumnModel Properties Property Data Type get is set bound Default Value column (indexed) TableColumn columns Enumeration columnCount int columnMargin int columnSelectionAllowed boolean selectedColumnCount int selectedColumns int[] selectionModel ListSelectionModel totalColumnWidth int 15.1.2.2 Events Any class implementing the TableColumnModel interface will have to support the ColumnModelEvent, which is generated when a column's view size, position, or extent size changes. The interface defines the standard addColumnModelListener() and removeColumnModelListener() methods, but the implementing class will be responsible for writing the code to fire the events when columns are added, removed, or moved. public void addColumnModelListener(TableColumnModelListener l) public void remove ColumnModelListener(TableColumnModelListener l) Add or remove a listener interested in changes to this column model. 15.1.2.3 Column Methods The TableColumnModel interface defines several methods for working with the columns in the model. public void addColumn(TableColumn column) Appends column to the current column model. public int getColumnIndex(Object identifier) public int getColumnIndexAtX(int xPixel) Return the column model (screen) index of a column, either with a header matching identifier, or at the specified xPixel location on the screen. public void moveColumn(int index, int newIndex) Moves the column at index to newIndex. Other columns should be shifted around as needed to accommodate the moved column. This visually relocates the column on the screen only. The table model does not change. [...]... result looks like Figure 15. 3 Figure 15. 3 A sorting column model; the columns were added as "In," "Names," "Order" Here's the code that puts the table and column models together: // ColumnExample .java - 410 - Java Swing – O’Reilly // A test of the JTable class using default table models and a convenience // constructor import java. awt.*; import javax .swing. *; import javax .swing. table.*; public class... DatabaseTest .java // Let's try to make one of these work // - 424 - Java Swing – O’Reilly import import import import java. awt.*; java. awt.event.*; javax .swing. *; javax .swing. table.*; public class DatabaseTest extends JFrame { JTextField hostField; JTextField queryField; QueryTableModel qtm; public DatabaseTest() { super("Database Test Frame"); addWindowListener(new BasicWindowMonitor()); setSize( 350 , 200);... - 4 25 - Java Swing – O’Reilly SQL or the JDBC code throughout this class, check out Database Programming with JDBC and Java, by George Reese (O'Reilly & Associates) // QueryTableModel .java // A basic implementation of the TableModel interface that fills out a Vector of // String[] structure from a query's result set // import java. sql.*; import java. io.*; import java. util.Vector; import javax .swing. *;... and a convenience // constructor // import java. awt.*; import javax .swing. *; public class MarketTable extends JFrame { public MarketTable() { - 423 - Java Swing – O’Reilly super("Dynamic Data Test"); setSize(300, 200); addWindowListener(new BasicWindowMonitor()); // set up our table model with a 5 second polling delay MarketDataModel mdm = new MarketDataModel (5) ; // Pick which stocks we want to watch... default model presumes that every cell is editable 15. 2 .5. 1 Properties The DefaultTableModel class provides default values to the properties inherited from the TableModel interface These values are shown in Table 15. 8 Table 15. 8, DefaultTableModel Properties Property columnCount* rowCount* Data Type int int get is set bound Default Value 0 0 15. 2 .5. 2 Events The DefaultTableModel class does not support... it.) // MYOSM .java // Make Your Own Stock Market: A simple stock market simulator that contains a // few stocks and their current prices (and deltas) It randomly adjusts the // prices on stocks to give a dynamic feel to the data // import javax .swing. *; import java. awt.*; import java. util.*; public class MYOSM extends JFrame implements Runnable { Stock[] market = { new Stock("JTree", 14 .57 ), new Stock("JTable",... getSelectionModel()) and attach a listener to that object - 409 - Java Swing – O’Reilly 15. 1.6 Implementing A Column Model Here's a custom column model that keeps all of its columns in alphabetical order as they get added: // SortingColumnModel .java // A simple extension of the DefaultTableColumnModel class that sorts // incoming columns // import javax .swing. table.*; public class SortingColumnModel extends DefaultTableColumnModel... requirements of a minimal table model, but it makes the table look more professional.) Here's the source code: // AbstractExample .java // A test of the JTable class using default table models and a convenience // constructor // import java. awt.*; import javax .swing. *; import javax .swing. table.*; public class AbstractExample extends JFrame { public AbstractExample() { super("Abstract Model JTable Test");... frame, the resulting table in Figure 15. 4 is exactly the same as the first example - 413 - Java Swing – O’Reilly Figure 15. 4 A JTable built with a custom TableModel class 15. 2.2.1 Fields protected EventListenerList listenerList The AbstractTableModel class adds a listener list for table model event listeners You can access the list with the add and remove methods 15. 2.2.2 Events public void addTableModelListener(TableModelListener... that can be used to encode information about the columns of the table (such as a localized name or class type), apart from the column model - 411 - Java Swing – O’Reilly 15. 2.1.1 Properties The TableModel interface supports the properties shown in Table 15. 5 The columnCount is the number of columns in the data model This does not have to match the number of columns reported by the column model Likewise, . actionPerformed() method: // ToolBarExample .java // import java. awt.*; import java. awt.event.*; import javax .swing. *; import javax .swing. border.*; import javax .swing. event.*; public class ToolBarExample. ColumnExample .java Java Swing – O’Reilly - 411 - // A test of the JTable class using default table models and a convenience // constructor. import java. awt.*; import javax .swing. *;. AbstractExample .java // A test of the JTable class using default table models and a convenience // constructor. // import java. awt.*; import javax .swing. *; import javax .swing. table.*;

Ngày đăng: 12/08/2014, 19:21

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan