天天看点

Java Swing sun官方书籍部分翻译

<!-- [if !mso]> <style> v/:* {behavior:url(#default#VML);} o/:* {behavior:url(#default#VML);} w/:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} </style> <![endif]--><!-- [if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:PunctuationKerning/> <w:DrawingGridVerticalSpacing>7.8 磅</w:DrawingGridVerticalSpacing> <w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery> <w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery> <w:ValidateAgainstSchemas/> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:Compatibility> <w:SpaceForUL/> <w:BalanceSingleByteDoubleByteWidth/> <w:DoNotLeaveBackslashAlone/> <w:ULTrailSpace/> <w:DoNotExpandShiftReturn/> <w:AdjustLineHeightInTable/> <w:BreakWrappedTables/> <w:SnapToGridInCell/> <w:WrapTextWithPunct/> <w:UseAsianBreakRules/> <w:DontGrowAutofit/> <w:UseFELayout/> </w:Compatibility> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> </w:WordDocument> </xml><![endif]--><!-- [if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" LatentStyleCount="156"> </w:LatentStyles> </xml><![endif]--><!-- [if gte mso 10]> <style> table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:"Times New Roman"; mso-ansi-language:#0400; mso-fareast-language:#0400; mso-bidi-language:#0400;} </style> <![endif]-->

Swing 2 Edito1

1. Swing 的特性

<1> Pluggable Look-and-Feels 可插入的实感外观, 可以动态的去替换。

<2> Lightweight Components 轻量级组件

<3> Swing 提供更广泛的组件

<4> Swing 可以替换它的插入效果. 通过替换Border

<5> Swing 组件有tooltips

Java Swing sun官方书籍部分翻译

2. UIManager.setLookAndFeel (lnfName);

SwingUtilities.updateComponentTreeUI ( frame );

JTable 学习

1.

JTable(Object[][] rowData, Object[] columnNames)

JTable(Vector rowData, Vector columnNames)

使用以上两个构造函数的不利点:

<1> 单元格都可以编辑

<2> By default, all columns in a table start out with equal width, and the columns automatically fill the entire width of the table,When the table becomes wider or narrower (which might happen when the user resizes the window containing the table), all the column widths change appropriately.

默认,所有的列都是相当的宽度,会自动填充整个表格的宽度 . 当调整表格的宽度,所有的列会自动的改变宽度 .

column = table.getColumnModel().getColumn(i);
      
if (i == 2) {
      
column.setPreferredWidth(100); //third column is bigger
      
} else {
      
column.setPreferredWidth(50);
      
}
      
TableColumn
                
 supplies getter and setter methods for the minimum, preferred, and maximum widths of a column, as well as a method for getting the current width. For an example of setting cell widths based on an approximation of the space needed to draw the cells' contents, see the          initColumnSizes                
 method in          TableRenderDemo.java                

.
      

User Selections

<1> The user can select a contiguous range of rows or an arbitrary set of rows

用户可以选择连续变化的行或者任意的行      
<2>Row Selection 
Column Selection 
Cell Selection
      
5.

      
6.

      
<1>A table model can have a set of listeners that are notified whenever the table data changes. Listeners are instances of          TableModelListener           
7.

      
Method Change
fireTableCellUpdated Update of specified cell.
fireTableRowsUpdated Update of specified rows
fireTableDataChanged Update of entire table (data only).
fireTableRowsInserted New rows inserted.
fireTableRowsDeleted Existing rows Deleted
fireTableStructureChanged Invalidate entire table, both data and structure
8.

      
9.

      
Using Custom Renderers

 
      
<1>You can set a type-specific cell renderer using the          JTable
                
 method          setDefaultRenderer                

. To specify that cells in a particular column should use a renderer, you use the          TableColumn                
 method          setCellRenderer                

. You can even specify a cell-specific renderer by creating a          JTable                
 subclass

      
<2>If extending          DefaultTableCellRenderer                
 is insufficient, you can build a renderer using another superclass. The easiest way is to create a subclass of an existing component, making your subclass implement the          TableCellRenderer                

 interface
      

<3> In the snapshot of

TableDialogEditDemo

, the renderer used for Favorite Color cells is a subclass of

JLabel

called

ColorRenderer

. Here are excerpts from

ColorRenderer.java

that show how it is implemented.

implements TableCellRenderer {
      
...
      
public ColorRenderer(boolean isBordered) {
      
this.isBordered = isBordered;
      
setOpaque(true); //MUST do this for background to show up.
      
}
      
public Component getTableCellRendererComponent(
      
JTable table, Object color,
      
boolean isSelected, boolean hasFocus,
      
int row, int column) {
      
Color newColor = (Color)color;
      
setBackground(newColor);
      
if (isBordered) {
      
if (isSelected) {
      
...
      
//selectedBorder is a solid border in the color
      
//table.getSelectionBackground().
      
setBorder(selectedBorder);
      
} else {
      
...
      
//unselectedBorder is a solid border in the color
      
//table.getBackground().
      
setBorder(unselectedBorder);
      
}
      
}
      
setToolTipText(...); //Discussed in the following section


      
return this;
      
}
      

Here is the code from

TableDialogEditDemo.java

that registers a

ColorRenderer

instance as the default renderer for all

Color

data:

table.setDefaultRenderer(Color.class, new ColorRenderer(true));

      

<4> To specify a cell-specific renderer, you need to define a

JTable

subclass that overrides the

getCellRenderer

method. For example, the following code makes the first cell in the first column of the table use a custom renderer:

public TableCellRenderer getCellRenderer(int row, int column) {
      
if ((row == 0) && (column == 0)) {
      
return weirdRenderer;
      
}
      
// else...
      
return super.getCellRenderer(row, column);
      
}
      

10.

Specifying Tool Tips for Cells

<1> By default, the tool tip text displayed for a table cell is determined by the cell's renderer. However, sometimes it can be simpler to specify tool tip text by overriding

JTable

's implementation of the

getToolTipText(MouseEvent)

method . This section shows you how to use both techniques.

<2>To add a tool tip to a cell using its renderer, you first need to get or create the cell renderer. Then, after making sure the rendering component is a

JComponent

, invoke the

setToolTipText

method on it

<3>JTable table = new JTable(new MyTableModel()) { 

      
//Implement table cell tool tips.
      
public String getToolTipText(MouseEvent e) {
      
String tip = null;
      
java.awt.Point p = e.getPoint();
      
int rowIndex = rowAtPoint(p);
      
int colIndex = columnAtPoint(p);
      
int realColumnIndex = convertColumnIndexToModel(colIndex);
      
if (realColumnIndex == 2) { //Sport column
      
tip = "This person's favorite sport to "
      
+ "participate in is: "
      
+ getValueAt(rowIndex, colIndex);
      
} else if (realColumnIndex == 4) { //Veggie column
      
TableModel model = getModel();
      
String firstName = (String)model.getValueAt(rowIndex,0);
      
String lastName = (String)model.getValueAt(rowIndex,1);
      
Boolean veggie = (Boolean)model.getValueAt(rowIndex,4);
      
if (Boolean.TRUE.equals(veggie)) {
      
tip = firstName + " " + lastName
      
+ " is a vegetarian";
      
} else {
      
tip = firstName + " " + lastName
      
+ " is not a vegetarian";
      
}
      
} else { //another column
      
//You can omit this part if you know you don't 
      
//have any renderers that supply their own tool 
      
//tips.
      
tip = super.getToolTipText(e);
      
}
      
return tip;
      
}
      
...
      

11

Specifying Tool Tips for Column Headers

<1> You can add a tool tip to a column header by setting the tool tip text for the table's

JTableHeader

. Often, different column headers require different tool tip text. You can change the text by overriding the table header's

getToolTipText

method. Alternately, you can invoke

TableColumn.setHeaderRenderer

to provide a custom renderer for the header.

<2> The following code implements the tool tips. Basically, it creates a subclass of

JTableHeader

that overrides the

getToolTipText(MouseEvent)

method so that it returns the text for the current column. To associate the revised table header with the table, the

JTable

method

createDefaultTableHeader

is overridden so that it returns an instance of the

JTableHeader

subclass.

null, // "First Name" assumed obvious
      
null, // "Last Name" assumed obvious
      
"The person's favorite sport to participate in",
      
"The number of years the person has played the sport",
      
"If checked, the person eats no meat"};
      
...
      
//Implement table header tool tips.
      
protected JTableHeader createDefaultTableHeader() {
      
return new JTableHeader(columnModel) {
      
public String getToolTipText(MouseEvent e) {
      
String tip = null;
      
java.awt.Point p = e.getPoint();
      
int index = columnModel.getColumnIndexAtX(p.x);
      
int realIndex = 
      
columnModel.getColumn(index).getModelIndex();
      
return columnToolTips[realIndex];
      
}
      
};
      
}
      

12

Sorting and Filtering

<1> Table sorting and filtering is managed by a sorter object. The easiest way to provide a sorter object is to set autoCreateRowSorter bound property to true:

JTable table = new JTable();

table.setAutoCreateRowSorter(true);

This action defines a row sorter that is an instance of javax.swing.table.TableRowSorter . This provides a table that does a simple locale-specific sort when the user clicks on a column header. This is demonstrated in TableSortDemo.java , as seen in this screen shot:

To have more control over sorting, you can construct an instance of TableRowSorter and specify that it is the sorter object for your table.

TableRowSorter<TableModel> sorter

= new TableRowSorter<TableModel>(table.getModel());

table.setRowSorter(sorter);

<2> When a table uses a sorter, the data the users sees may be in a different order than that specified by the data model, and may not include all rows specified by the data model. The data the user actually sees is known as the view , and has its own set of coordinates. JTable provides methods that convert from model coordinates to view coordinates — convertColumnIndexToView and convertRowIndexToView — and that convert from view coordinates to model coordinates — convertColumnIndexToModel and convertRowIndexToModel .

NOTE: When using a sorter, always remember to translate cell coordinates

13

Using a Combo Box as an Editor

14

Using Other Editors

<1> What if you want to specify an editor other than a text field, check box, or combo box? As

DefaultCellEditor

does not support other types of components, you must do a little more work. You need to create a class that implements the

TableCellEditor

interface. The

AbstractCellEditor

class is a good superclass to use. It implements

TableCellEditor

's superinterface,

CellEditor

, saving you the trouble of implementing the event firing code necessary for cell editors

<2>Your cell editor class needs to define at least two methods —

getCellEditorValue

and

getTableCellEditorComponent

. The

getCellEditorValue

method, required by

CellEditor

, returns the cell's current value. The

getTableCellEditorComponent

method, required by

TableCellEditor

, should configure and return the component that you want to use as the editor.

<3>Here is the code, taken from

ColorEditor.java

, that implements the cell editor.

implements TableCellEditor,
      
ActionListener {
      
Color currentColor;
      
JButton button;
      
JColorChooser colorChooser;
      
JDialog dialog;
      
protected static final String EDIT = "edit";
      
public ColorEditor() {
      
button = new JButton();
      
button.setActionCommand(EDIT);
      
button.addActionListener(this);
      
button.setBorderPainted(false);
      
//Set up the dialog that the button brings up.
      
colorChooser = new JColorChooser();
      
dialog = JColorChooser.createDialog(button,
      
"Pick a Color",
      
true, 
//modal
      
colorChooser,
      
this, 
//OK button handler
      
null); //no CANCEL button handler
      
}
      
public void actionPerformed(ActionEvent e) {
      
if (EDIT.equals(e.getActionCommand())) {
      
//The user has clicked the cell, so
      
//bring up the dialog.
      
button.setBackground(currentColor);
      
colorChooser.setColor(currentColor);
      
dialog.setVisible(true);
      
fireEditingStopped(); //Make the renderer reappear.
      
} else { //User pressed dialog's "OK" button.
      
currentColor = colorChooser.getColor();
      
}
      
}
      
//Implement the one CellEditor method that AbstractCellEditor doesn't.
      
public Object getCellEditorValue() {
      
return currentColor;
      
}
      
//Implement the one method defined by TableCellEditor.
      
public Component getTableCellEditorComponent(JTable table,
      
Object value,
      
boolean isSelected,
      
int row,
      
int column) {
      
currentColor = (Color)value;
      
return button;
      
}
      

As you can see, the code is pretty simple. The only part that is a bit tricky is the call to

fireEditingStopped

at the end of the editor button's action handler. Without this call, the editor would remain active, even though the modal dialog is no longer visible. The call to

fireEditingStopped

lets the table know that it can deactivate the editor, letting the cell be handled by the renderer again.

15

Using an Editor to Validate User-Entered Text

16

Printing

JTextComponent

<!-- [if !mso]> <style> v/:* {behavior:url(#default#VML);} o/:* {behavior:url(#default#VML);} w/:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} </style> <![endif]--><!-- [if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:PunctuationKerning/> <w:DrawingGridVerticalSpacing>7.8 磅</w:DrawingGridVerticalSpacing> <w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery> <w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery> <w:ValidateAgainstSchemas/> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:Compatibility> <w:SpaceForUL/> <w:BalanceSingleByteDoubleByteWidth/> <w:DoNotLeaveBackslashAlone/> <w:ULTrailSpace/> <w:DoNotExpandShiftReturn/> <w:AdjustLineHeightInTable/> <w:BreakWrappedTables/> <w:SnapToGridInCell/> <w:WrapTextWithPunct/> <w:UseAsianBreakRules/> <w:DontGrowAutofit/> <w:UseFELayout/> </w:Compatibility> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> </w:WordDocument> </xml><![endif]--><!-- [if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" LatentStyleCount="156"> </w:LatentStyles> </xml><![endif]--><!-- [if gte mso 10]> <style> table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:"Times New Roman"; mso-ansi-language:#0400; mso-fareast-language:#0400; mso-bidi-language:#0400;} </style> <![endif]-->

Java Swing sun官方书籍部分翻译

LookAndFeel

The abstract base class from which all the different L&Fs extend. It defines a number of static convenience methods, as well as some abstract methods required by every L&F.

UIDefaults

An L&F is responsible for defining a set of default properties. UIDefaults is a Hashtable subclass that holds these properties. The properties include UIClassID to ComponentUI subclass mappings (e.g., "TreeUI" to MetalTreeUI) as well as lower-level defaults, such as colors and fonts.

UIDefaults.ActiveValue and UIDefaults.LazyValue

These inner interfaces of UIDefaults enable some optimizations for resource values.

UIResource

This is an empty interface (like Serializable or Cloneable) used to tag property values. It allows values defined by the L&F to be distinguished from values set by the user, as described in Section 26.3.5 later in this chapter.

UIManager

If you've ever changed the L&F of a Swing program at runtime, you're probably already familiar with this class. UIManager is responsible for tracking a global view of the L&Fs available in an application. It keeps track of the currently installed L&F and provides a mechanism to change the L&F. All of its methods are static, but it does provide a mechanism that allows multiple applets within a single virtual machine to use different L&Fs.

UIManager.LookAndFeelInfo

This inner class is used to describe available L&Fs without actually having to load the L&F classes. UIManager uses this class to provide a list of available L&Fs.

ComponentUI

This is the base class common to all UI delegates. It defines all of the methods related to painting and sizing that the different delegate subclasses must implement.

JComponent

You're certainly familiar with this class by now 梚t's the base class for all of the Swing components. We include it in this diagram to show that at any time, each JComponent has a reference to a single ComponentUI. ComponentUI objects may, however, be shared by multiple components. JComponent was covered in gory detail back in Chapter 3 .