📄 swing2.html
字号:
}
</PRE>
<CODE>JTree</CODE>, <CODE>JTable</CODE> and <CODE>JList</CODE> are
probably the most common models you will want to customize. But you
can use models such as <CODE>SingleSelectionModel</CODE> for general
data manipulation. The <CODE>SingleSelectionModel</CODE> class lets you
specify how data is selected in a component.
<A NAME="render"></A>
<H3>Custom Cell Rendering</H3>
As you learned above, many components have a default cell renderer
to paint each element in a table, tree or list. The default
cell renderer is usually a <CODE>JLabel</CODE> and displays a
<CODE>String</CODE> representation of the data element.
<P>
A simple custom cell renderer can extend the <CODE>DefaultXXXCellRenderer</CODE>
class to provide additional customization in the <CODE>getXXXCellRenderer</CODE>.
The <CODE>DefaultTableCellRenderer</CODE> and <CODE>DefaultTreeCellRenderer</CODE>
Components both use a <CODE>JLabel</CODE> to render the cell.
This means any customization that can be applied to a <CODE>JLabel</CODE>
can also be used in the <CODE>JTable</CODE> or <CODE>JTree</CODE> cell.
<P>
For example, the following renderer sets the background color of the
component if the auction item has received a high number of bids:
<PRE>
class CustomRenderer extends DefaultTableCellRenderer {
public Component getTableCellRendererComponent(
JTable table,Object value,
boolean isSelected,
boolean hasFocus,
int row, int column) {
Component comp =
super.getTableCellRendererComponent(
table,value,isSelected,hasFocus,
row,column);
JLabel label = (JLabel)comp;
if(((Integer)value).intValue() >= 30) {
label.setIcon(new ImageIcon("Hot.gif"));
} else {
label.setIcon(new ImageIcon("Normal.gif"));
}
return label;
}
}
</PRE>
The renderer is set on a column like this:
<PRE>
CustomRenderer custom = new CustomRenderer();
custom.setHorizontalAlignment(JLabel.CENTER);
scrollColumnModel.getColumn(2).setCellRenderer(
custom);
</PRE>
If the component being displayed inside the <CODE>JTable</CODE> column requires
more functionality than is available using a <CODE>JLabel</CODE>, you can
create your own <CODE>TableCellRenderer</CODE>. This next code
example uses a <CODE>JButton</CODE> as the renderer cell.
<PRE>
class CustomButtonRenderer extends JButton
implements TableCellRenderer {
public CustomButtonRenderer() {
setOpaque(true);
}
public Component getTableCellRendererComponent(
JTable table, Object value,
boolean isSelected,
boolean hasFocus, int row,
int column) {
if (isSelected) {
((JButton)value).setForeground(
table.getSelectionForeground());
((JButton)value).setBackground(
table.getSelectionBackground());
} else {
((JButton)value).setForeground(table.getForeground());
((JButton)value).setBackground(table.getBackground());
}
return (JButton)value;
}
}
</PRE>
Like the default <CODE>JLabel</CODE> cell renderer, this class relies on
an underlying component (in this case <CODE>JButton</CODE>) to do the painting.
Selection of the cell toggles the button colors. As before, the cell renderer
is secured to the appropriate column of the auction table with the
<CODE>setCellRenderer</CODE> method:
<PRE>
scrollColumnModel.getColumn(3).setCellRenderer(
new CustomButtonRenderer());
</PRE>
Alternately, all <CODE>JButton</CODE> components can be configured to
use the <CODE>CustomButtonRenderer</CODE> in the table with a call to
<CODE>setDefaultRenderer</CODE> as follows:
<PRE>
table.setDefaultRenderer(
JButton.class, new CustomButtonRenderer());
</PRE>
<A NAME="edit"></A>
<H3>Custom Cell Editing</H3>
In the same way that you can configure how a cell is painted in a
<CODE>JTable</CODE> or <CODE>JTree</CODE> component, you can also
configure how an editable cell responds to edits. One difference between
using cell editors and cell renderers is there is a
<CODE>DefaultCellEditor</CODE> for all components, but
no <CODE>DefaultTableCellEditor</CODE> for table cells.
<P>
While separate renderers exist for <CODE>JTree</CODE> and <CODE>JTable</CODE>,
a single <CODE>DefaultCellEditor</CODE> class implements both the
<CODE>TableCellEditor</CODE> and <CODE>TreeCellEditor</CODE> interfaces.
However, the <CODE>DefaultCellEditor</CODE> class has constructors for only
the <CODE>JComboBox</CODE>, <CODE>JCheckBox</CODE>, and <CODE>JTextField</CODE>
components. The <CODE>JButton</CODE> class does not map to any of these
constructors so a dummy <CODE>JCheckBox</CODE> is created to satisfy the
requirements of the <CODE>DefaultCellEditor</CODE> class.
<P>
This next example uses a custom button editor that displays the number
of days left in the auction when the button is double clicked. The
double click to trigger the action is specified by setting the value
<CODE>clickCountToStart</CODE> to two. An exact copy of the
<CODE>getTableCellEditorComponent</CODE> method paints the button in edit
mode. A <CODE>JDialog</CODE> component that displays the number
of days left appears when the <CODE>getCellEditorValue</CODE> method
is called.
The value for the number of days left is calculated by moving the current
calendar date towards the end date. The <CODE>Calendar</CODE> class does
not have a method that expresses a difference in two dates in anything
other than the milliseconds between those two dates.
<PRE>
class CustomButtonEditor extends DefaultCellEditor {
final JButton mybutton;
JFrame frame;
CustomButtonEditor(JFrame frame) {
super(new JCheckBox());
mybutton = new JButton();
this.editorComponent = mybutton;
this.clickCountToStart = 2;
this.frame=frame;
mybutton.setOpaque(true);
mybutton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
fireEditingStopped();
}
});
}
protected void fireEditingStopped() {
super.fireEditingStopped();
}
public Object getCellEditorValue() {
JDialog jd= new JDialog(frame, "Time left");
Calendar today=Calendar.getInstance();
Calendar end=Calendar.getInstance();
SimpleDateFormat in=new SimpleDateFormat("yyyy-MM-dd");
try {
end.setTime(in.parse(mybutton.getText()));
} catch (Exception e){
System.out.println("Error in date"+mybutton.getText()+e);
}
int days = 0;
while(today.before(end)) {
today.roll(Calendar.DATE,true);
days++;
}
jd.setSize(200,100);
if (today.after(end)) {
jd.getContentPane().add(new JLabel("Auction completed"));
} else {
jd.getContentPane().add(new JLabel("Days left="+days));
}
jd.setVisible(true);
return new String(mybutton.getText());
}
public Component getTableCellEditorComponent(JTable table,
Object value, boolean isSelected,
int row, int column) {
((JButton) editorComponent).setText(((
JButton)value).getText());
if (isSelected) {
((JButton) editorComponent).setForeground(
table.getSelectionForeground());
((JButton) editorComponent).setBackground(
table.getSelectionBackground());
} else {
((JButton) editorComponent).setForeground(
table.getForeground());
((JButton) editorComponent).setBackground(
table.getBackground());
}
return editorComponent;
}
}
</PRE>
<A NAME="events"></A>
<H3>Specialized Event Handling</H3>
Project Swing uses the event handling classes available
in the AWT API since JDK 1.1. However, some new APIs are available in
the <CODE>SwingUtilities</CODE> class that are used to add some control
over the event queue. The two new event handling methods are
<CODE>invokeLater</CODE> and <CODE>invokeAndWait</CODE>.
The <CODE>invokeAndWait</CODE>
method waits for the event to be processed in the event queue.
<P>
These methods are often used to request focus on a component after
another event has occurred that might affect the component focus. You
can return the focus by calling the <CODE>invokeLater</CODE> method and
passing a <CODE>Thread</CODE>:
<PRE>
JButton button =new JButton();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
button.requestFocus();
}
});
</PRE>
<A NAME="direction"></A>
<H3>Project Swing Directions</H3>
While the basic architecture of Project Swing has stayed true
to its original design, many optimizations and improvements
have been made to components like <CODE>JTable</CODE> and in areas such as
scrolling. Add to this the Java HotSpot<FONT SIZE=-2><SUP>TM</SUP></FONT>
Performance Engine, which greatly reduces the cost of object creation,
and Project Swing can boast its best performance to date.
<P>
However, as seen in the
<A HREF="http://developer.java.sun.com/developer/onlineTraining/Programming/JDCBook/perf3.html#analysis">Analyze a Program</A> section in the
Performance chapter, a simple
700x300 table requires nearly half a megabyte of memory when double buffered.
The creation of ten tables would probably require swapping memory to disk,
severly affecting performance on low-end machines.
<P ALIGN="RIGHT">
<FONT SIZE="-1">[<A HREF="#top">TOP</A>]</FONT>
</FONT>
<!-- ================ -->
<!-- End Main Content -->
<!-- ================ -->
</TD>
</TR>
</TABLE>
<!-- Copyright Insert -->
<BR CLEAR="ALL">
<FORM ACTION="/cgi-bin/search.cgi" METHOD="POST">
<TABLE WIDTH="100%" CELLPADDING="0" BORDER="0" CELLSPACING="5">
<TR>
<TD VALIGN="TOP">
<P ALIGN=CENTER>
<FONT SIZE="-1" COLOR="#999999" FACE="Verdana, Arial, Helvetica, sans-serif">
[ This page was updated: <!-- new date --> 3-Nov-99 ]</font></P>
</TD>
</TR>
<TR>
<TD BGCOLOR="#CCCCCC">
<IMG SRC="/images/pixel.gif" HEIGHT="1" WIDTH="1" ALT=""></TD>
</TR>
<TR>
<TD>
<CENTER>
<FONT SIZE="-2" FACE="Verdana, Arial, Helvetica, sans-serif">
<A HREF="http://java.sun.com/products/">Products & APIs</A> |
<A HREF="/developer/index.html">Developer Connection</A> |
<A HREF="/developer/infodocs/index.shtml">Docs & Training</A> |
<A HREF="/developer/support/index.html">Online Support</A><BR>
<A HREF="/developer/community/index.html">Community Discussion</A> |
<A HREF="http://java.sun.com/industry/">Industry News</A> |
<A HREF="http://java.sun.com/solutions">Solutions Marketplace</A> |
<A HREF="http://java.sun.com/casestudies">Case Studies</A>
</FONT>
</CENTER>
</TD>
</TR>
<TR>
<TD BGCOLOR="#CCCCCC">
<IMG SRC="/images/pixel.gif" HEIGHT="1" WIDTH="1" ALT=""></TD>
</TR>
<TR>
<TD ALIGN="CENTER">
<FONT SIZE="-2" FACE="Verdana, Arial, Helvetica, sans-serif">
<A HREF="http://java.sun.com/docs/glossary.html">Glossary</A> -
<A HREF="http://java.sun.com/applets/">Applets</A> -
<A HREF="http://java.sun.com/docs/books/tutorial/">Tutorial</A> -
<A HREF="http://java.sun.com/jobs/">Employment</A> -
<A HREF="http://java.sun.com/nav/business/">Business & Licensing</A> -
<A HREF="http://java.sun.com/javastore/">Java Store</A> -
<A HREF="http://java.sun.com/casestudies/">Java in the Real World</A>
</FONT>
</TD>
</TR>
<TR>
<TD>
<CENTER>
<FONT SIZE="-2" FACE="Verdana, Arial, Helvetica, sans-serif">
<a href="/siteinfo/faq.html">FAQ</a> |
<a href="/feedback/index.html">Feedback</a> |
<a href="http://www.dynamicdiagrams.net/mapa/cgi-bin/help.tcl?db=javasoft&dest=http://java.sun.com/">Map</a> |
<A HREF="http://java.sun.com/a-z/index.html">A-Z Index</A>
</FONT>
</CENTER>
</TD>
</TR>
<TR>
<TD>
<TABLE WIDTH="100%" CELLPADDING="0" BORDER="0" CELLSPACING="0">
<TR>
<TD WIDTH="50%">
<FONT SIZE="-2" FACE="Verdana, Arial, Helvetica, sans-serif">
For more information on Java technology<BR>
and other software from Sun Microsystems, call:<BR>
</FONT>
<FONT SIZE="-1" FACE="Verdana, Arial, Helvetica, sans-serif">
(800) 786-7638<BR></FONT>
<FONT SIZE="-2" FACE="Verdana, Arial, Helvetica, sans-serif">
Outside the U.S. and Canada, dial your country's
<A HREF="http://www.att.com/business_traveler/attdirecttollfree/">AT&T Direct Access Number</A> first.<BR>
</FONT>
</TD>
<TD ALIGN="RIGHT" WIDTH="50%">
<A HREF="http://www.sun.com"><IMG SRC="/images/lgsun.gif" width="64" height="30" border="0" ALT="Sun Microsystems, Inc."></A><BR>
<FONT SIZE="-2" FACE="Verdana, Arial, Helvetica, sans-serif">
Copyright © 1995-99
<A HREF="http://www.sun.com">Sun Microsystems, Inc.</A><BR>
All Rights Reserved.
<a href="http://www.sun.com/share/text/SMICopyright.html">Legal Terms</a>.
<A HREF="http://www.sun.com/privacy/">Privacy Policy</A>.
</FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
</FORM>
<!-- End Copyright Insert -->
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -