??xml version="1.0" encoding="utf-8" standalone="yes"?>
在用JTableӞ用户往往希望改变它缺省的渲染方式Q比如用间隔色的行Q对特定的单元格q行Ҏ(gu)颜色昄{,q对一些可视化~程环境的表格ƈ不是一件容易的事?br /> 在Java Swing~程中我们可以用DefaultTableCellRenderer的子cL染表格来辑ֈq个目的Q实现和使用它都非常Ҏ(gu)?/p>
渲染效果一Q?/p>
步骤一Q实C个javax.swing.table.DefaultTableCellRenderer的子c?/p>
/**
* 间隔色表格渲染类
*/
public class ColorTableCellRenderer extends DefaultTableCellRenderer {
private static final long serialVersionUID = -3378036327580475639L;
public Component getTableCellRendererComponent(
JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
// 得到单元?br />
Component cell =
super.getTableCellRendererComponent(
table,
value,
isSelected,
hasFocus,
row,
column);
// q行渲染
if (hasFocus) {
// 如果获得焦点则设|背景色为红?br />
cell.setBackground(Color.red);
//cell.setForeground(Color.black);
} else {
if ((row % 2) == 0) {
// 偶数行设|ؓ白色
cell.setBackground(Color.white);
} else {
// 奇数行设|ؓ蓝色
cell.setBackground(Color.cyan);
}
}
return cell;
}
}
步骤二:ColorTableCellRenderer讄格的渲染?/p>
try {
ColorTableCellRenderer cellRender = new ColorTableCellRenderer();
table.setDefaultRenderer(Class.forName("java.lang.Object"),
cellRender);
} catch (Exception e) {
e.printStackTrace();
}
实现一个将特定单元D|ؓU色的表格渲染器
如右Q如果想成员年龄大?7的单元格讄为红艌Ӏ?br />
AgeTableCellRenderer的代?/p>
public class AgeTableCellRenderer extends DefaultTableCellRenderer {
private static final long serialVersionUID = -334535475639L;
public Component getTableCellRendererComponent(
JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
// 得到单元?br />
Component cell =
super.getTableCellRendererComponent(
table,
value,
isSelected,
hasFocus,
row,
column);
// 先把所有单元格讄为白?br />
cell.setBackground(Color.white);
// q行渲染
if (table.getColumnName(column).equals("q龄") ) { // 如果列名{于“q龄”
// 取得单元格的文字
String strValue=(String)value;
if(Pattern.matches("\\d+", strValue)){
if(Integer.parseInt(strValue)>37){
// 如果是数字且值大?7Q将单元D景设|ؓU色
cell.setBackground(Color.red);
}
}
}
return cell;
}
}
?wi)可以用囑Ş的方式显CZ多的节点以及它们之间的关p,最常见的树(wi)的例子就是目录树(wi)?br />
所有组成树(wi)的元素都成ؓ节点QNodeQ,一|(wi)的最层的节点称为根节点Q如ProgramQ而没有子节点的节Ҏ(gu)为叶子节点,如domain。在层次l构中,上层的节Ҏ(gu)下层节点的父节点Q而下层节Ҏ(gu)上层节点的子节点Q如图:Program是C# Programs和Programs的父节点QFileBatchRemaer20070801094605是C# Programes的子节点?br />
有关?wi)JTree的类和接?/strong>
JTree 昄?wi)的核心基本cR?br /> TreeModel 定义了树(wi)的数据模型接?br /> DefaultTreeModel 默认的树(wi)模型接口实现c?br /> TreeModelListener ?wi)模型的事g监听?br /> TreePath ?wi)\径。一个\径就是一个对象数l,对应于树(wi)模型中从根节点到选定节点上的所有节炚w合。数l的W一个元素是根节点,按树(wi)的层ơ关pMơ在数组中给Z间节点,最后一个元素是选定的节炏V?br /> MutableTreeNode ?wi)节?gu)口。对应树(wi)中的节点。树(wi)节点接口定义了与父子节点有关的方法。因此,利用?wi)节点可以遍历整|(wi)?br /> DedaultMutableTreeNode 默认的树(wi)节点的实现类?br /> TreeSelectionModel 定义了在?wi)上的选择节点的数据模型接口。树(wi)选择模型军_了选择节点的策略以及被选择节点的信息?br /> TreeSelectionModelListener ?wi)选择模型事g的监听器?/p>
代码实例Q构Z|(wi)
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Java");
DefaultMutableTreeNode j2seNode=new DefaultMutableTreeNode("J2SE(JavaSE)");
DefaultMutableTreeNode swingNode=new DefaultMutableTreeNode("Swing");
DefaultMutableTreeNode socketNode=new DefaultMutableTreeNode("Socket");
DefaultMutableTreeNode threadNode=new DefaultMutableTreeNode("Thread");
j2seNode.add(swingNode);
j2seNode.add(socketNode);
j2seNode.add(threadNode);
DefaultMutableTreeNode j2eeNode=new DefaultMutableTreeNode("J2EE(JavaEE)");
DefaultMutableTreeNode jspservletNode=new DefaultMutableTreeNode("Jsp/Servlet");
DefaultMutableTreeNode jdbcNode=new DefaultMutableTreeNode("JDBC");
DefaultMutableTreeNode javaMailNode=new DefaultMutableTreeNode("Java Mail");
j2eeNode.add(jspservletNode);
j2eeNode.add(jdbcNode);
j2eeNode.add(javaMailNode);
root.add(j2seNode);
root.add(j2eeNode);
tree = new JTree(root);
相关语句解释
// 创徏一个树(wi)节点Q文字ؓJ2SE(JavaSE)
DefaultMutableTreeNode j2seNode=new DefaultMutableTreeNode("J2SE(JavaSE)");
// 创徏一个文字ؓ“Swing”的节点,d在节点j2seNode?br />
DefaultMutableTreeNode swingNode=new DefaultMutableTreeNode("Swing");
j2seNode.add(swingNode);
// 创徏一个文字ؓJava的节点作为根节点Q然后以此根节点构徏一|(wi)。j2seNodeQj2eeNode挂在root ?br />
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Java");
.......
root.add(j2seNode);
root.add(j2eeNode);
tree = new JTree(root);
注意Q?JTree和JTextAreaQJTable一P也需要放在一个JScrollPane中?/p>
l树(wi)控gd监听
tree.addTreeSelectionListener(new TreeSelectionListener() {
public void valueChanged(TreeSelectionEvent evt) {
// 取得选择状态变化的所有\?br />
TreePath[] paths = evt.getPaths();
for (int i=0; i<paths.length; i++) {
// 如果处于选择状?br />
if (evt.isAddedPath(i)) {
// \径{化ؓ节点数组
Object[] nodes=paths[i].getPath();
// 得到最后一个节?即选择的节?br />
DefaultMutableTreeNode node=(DefaultMutableTreeNode)nodes[nodes.length-1];
// 输出节点?br />
System.out.println(node.toString());
}
}
}
});
额外的一点美化工作:渲染节点
// 讑֮叶节点图?br />
Icon leafIcon = new ImageIcon(TreePanel.class.getResource("/leaf.gif"));
// 讑֮关闭状态节点图?br />
Icon closedIcon = new ImageIcon(TreePanel.class.getResource("/close.gif"));
// 讑֮打开状态节点图?br />
Icon openIcon = new ImageIcon(TreePanel.class.getResource("/open.gif"));
// 取得?wi)的渲染?br />
DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer)tree.getCellRenderer();
renderer.setLeafIcon(leafIcon);// 讑֮叶节点图?br />
renderer.setClosedIcon(closedIcon);// 讑֮关闭状态节点图?br />
renderer.setOpenIcon(openIcon);// 讑֮打开状态节点图?/p>
JTabbedPane在Swing中实现选项H格Q它可以把多个组件放在多个选项卡中Q从而ə面不致拥挤Q其选项卡的形式也能为程序增色不?br /> 选项H格和分隔窗格类|创徏出来需要添加到讄好布局的面板中Q通常我们可以讄布局?*1的网格布局或是边界布局?br /> 选项H格内部可以攄多个选项,每个选项都可以容纳一个JPanel作ؓ子组Ӟ我们只要设计好需要添加到选项늚面板卛_?/p>
JTabbedPane效果
创徏JTabbedPane
// 创徏选项H格
JTabbedPane tabPane = new JTabbedPane();
// 讄面板布局为网格布局
this.setLayout(new GridLayout(1,1));
tabPane.setTabPlacement(JTabbedPane.TOP);// 讑֮选项卡放在上?br />
this.add(tabPane);// 选项H格攄在面板中
// 创徏一个StockPanel面板q添加到选项H格,q是指定图标的方?br />
StockPanel stockPanel=new StockPanel();
tabPane.addTab("库存面", new ImageIcon(TabbedPanel.class
.getResource("/stock.gif")), stockPanel);
ImportPanel importPanel=new ImportPanel();
tabPane.addTab("q货面", new ImageIcon(TabbedPanel.class
.getResource("/import.gif")), importPanel);
// 创徏一个SaledPanel面板q添加到选项H格,q是不指定图标的Ҏ(gu)
SaledPanel saledPanel=new SaledPanel();
tabPane.addTab("已售面", saledPanel);
// 选择W一个选项ؓ当前选择的选项?br />
tabPane.setSelectedIndex(0);
创徏分隔H格CZ
// 创徏分隔H口,W一个参数指定了分隔的方?JSplitPane.HORIZONTAL_SPLIT表示水^分隔,另外一个选项是JSplitPane.VERTICAL_SPLIT,表示垂直分隔;另外两个参数是放|在该分隔窗格的lg.
JSplitPane splitPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, tablePanel, textPanel);
// 讄分隔器的位置,可以用整?像素)或百分比来指?
splitPanel.setDividerLocation(200);
// 讄分隔器是否显C用来展开/折叠分隔器的控g
splitPanel.setOneTouchExpandable(true);
// 讄分隔器的大小,单位为像?br /> splitPanel.setDividerSize(5);
// 分隔窗口添加到容器?br />
setLayout(new BorderLayout());
add(splitPanel, BorderLayout.CENTER);
在Swing?事g响应是通过监听器对象来处理事g的方式实行的,q种方式被称Z件委托模?
以JButton举例,它内部有一个名为listenerList的链?在点L钮时,会生一个ActionEvent事g,此后内部会依ơ调用位于listenerList中的每一个actionListener子类实例的actionPerformedҎ(gu),q就是事件响应的q程.
当调用JButton的addActionListenerҎ(gu)? 外界actionListener子类实例的指针就被放入了listenerList?当按钮点M件生时,q个实例的actionPerformedҎ(gu)׃被调?从而按钮的点击事g处理p委托CactionListener子类实例中进行处?
实现ActionListener的三U方?/strong>
1.实现一个ActionListener子类,再把按钮的事件响应委托给q个子类的实例处?q种方式q不常用,我在q里列出是ؓ了教?
2.让界面类实现ActionListener接口,再把事g响应委托l界面类.q种方式适合于处理一些短简单或要求内聚的事件响?
3.用匿名类实现ActionListener接口,再把事g委托l这个匿名类的实?q种方式是Swing事g处理的主?
方式一:实现一个ActionListener子类
// 实现了ActionListener接口的类
public class Button3ActionListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
String buttonText=((JButton)e.getSource()).getText();
System.out.println("你按下了" + buttonText);
}
}
// l按钮三d事g处理
button3.addActionListener(new Button3ActionListener());
方式?让界面类实现ActionListener接口
public class MyFrame extends JFrame implements ActionListener{
public MyFrame() {
....
button2.addActionListener(this);
}
/**
* 按钮二的事g响应在此
*/
public void actionPerformed(ActionEvent e) {
if(e.getSource()==button2){
showMsg("你按下了" + button2.getText());
}
}
}
方式?用匿名类的方式添加事件响?/strong>
button1 = new JButton("按钮一");
button1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showMsg("你按下了" + button1.getText());
}
});
双昄?strong>创徏H口的代?/strong>和JFrame的几个常用函?
public class MyFrame extends JFrame {
private static final long serialVersionUID = 1379963724699883220L;
/**
* 构造函?br />
*
*/
public MyFrame() {
// 讄H口标题
this.setTitle("E序标题");
// 定位H口
this.setLocation(20, 20);
// 讄H口大小
this.setSize(480, 320);
// 昄H口
setVisible(true);
}
public static void main(String[] args){
new MyFrame();
}
}
窗口定位在屏幕正中
使用Toolkit.getDefaultToolkit().getScreenSize()Ҏ(gu)可以取得屏幕的大?再调用setLocation函数可以程序定位在屏幕正中.
public class MyFrame extends JFrame {
private static final long serialVersionUID = 1379963724699883220L;
/**
* 构造函?br />
*
*/
public MyFrame() {
// 讄H口标题
this.setTitle("E序标题");
// 讄E序大小q定位程序在屏幕正中
setSizeAndCentralizeMe(480, 320);
// 昄H口
setVisible(true);
}
// 讄E序大小q定位程序在屏幕正中
private void setSizeAndCentralizeMe(int width, int height) {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
this.setSize(width, height);
this.setLocation(screenSize.width / 2 - width / 2, screenSize.height
/ 2 - height / 2);
}
public static void main(String[] args){
new MyFrame();
}
}
点击H口右上角的关闭按钮关闭H口,退出程?/strong>
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)可以辑ֈ此功?否则按关闭按钮窗口关闭但不退出程?
public class MyFrame extends JFrame {
private static final long serialVersionUID = 1379963724699883220L;
/**
* 构造函?br />
*
*/
public MyFrame() {
// 讄H口标题
this.setTitle("E序标题");
// 讄E序大小q定位程序在屏幕正中
setSizeAndCentralizeMe(480, 320);
// 昄H口
setVisible(true);
// 点击H口右上角的关闭按钮关闭H口,退出程?br />
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
// 讄E序大小q定位程序在屏幕正中
private void setSizeAndCentralizeMe(int width, int height) {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
this.setSize(width, height);
this.setLocation(screenSize.width / 2 - width / 2, screenSize.height
/ 2 - height / 2);
}
public static void main(String[] args){
new MyFrame();
}
}
dH口关闭事g处理
// 点击H口右上角的关闭按钮关闭H口,退出程?br />
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.out.println("E序退?");
System.exit(0);
}
});
上面的代码实C一个WindowAdapter的匿名类,q将它注册ؓH口事g的监听器.
public class MyFrame extends JFrame {
private static final long serialVersionUID = 1379963724699883220L;
/**
* 构造函?br />
*
*/
public MyFrame() {
// 讄H口标题
this.setTitle("E序标题");
// 讄E序大小q定位程序在屏幕正中
setSizeAndCentralizeMe(480, 320);
// 昄H口
setVisible(true);
// 点击H口右上角的关闭按钮关闭H口,退出程?br />
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.out.println("E序退?");
System.exit(0);
}
});
}
// 讄E序大小q定位程序在屏幕正中
private void setSizeAndCentralizeMe(int width, int height) {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
this.setSize(width, height);
this.setLocation(screenSize.width / 2 - width / 2, screenSize.height
/ 2 - height / 2);
}
public static void main(String[] args) {
new MyFrame();
}
}
讄E序感观
UIManager.getInstalledLookAndFeels()可得到可用的感观数组,然后取数l中元素的getClassName()Ҏ(gu)可得到感观类?再调?br />
UIManager.setLookAndFeel(strLookFeel); SwingUtilities.updateComponentTreeUI(this);
Ҏ(gu)可设|窗口感?
public class MyFrame extends JFrame {
/**
* 构造函?br />
*
*/
public MyFrame() {
// 讄H口标题
this.setTitle("E序标题");
// 讄E序大小q定位程序在屏幕正中
setSizeAndCentralizeMe(480, 320);
// 昄H口
setVisible(true);
// 讄E序感观
setupLookAndFeel();
....;
}
...
// 讄E序感观
private void setupLookAndFeel() {
// 取得pȝ当前可用感观数组
UIManager.LookAndFeelInfo[] arr = UIManager.getInstalledLookAndFeels();
Random random = new Random();
String strLookFeel=arr[random.nextInt(arr.length)].getClassName();
try {
UIManager.setLookAndFeel(strLookFeel);
SwingUtilities.updateComponentTreeUI(this);
} catch (Exception e) {
System.out.println("Can't Set Lookandfeel Style to " + strLookFeel);
}
}
....
}
讄E序感观q_的感?/strong>
UIManager.getCrossPlatformLookAndFeelClassName()可得到跨q_的感?
public class MyFrame extends JFrame {
public MyFrame() {
// 讄H口标题
this.setTitle("E序标题");
// 讄E序大小q定位程序在屏幕正中
setSizeAndCentralizeMe(480, 320);
// 昄H口
setVisible(true);
// 讄E序感观
setupLookAndFeel();
}
// 讄E序感观
private void setupLookAndFeel() {
String strLookFeel = UIManager.getCrossPlatformLookAndFeelClassName();
try {
UIManager.setLookAndFeel(strLookFeel);
} catch (Exception e) {
System.out.println("Can't Set Lookandfeel Style to " + strLookFeel);
}
}
}
JPanelcd用来作ؓ一批组件如JButton,JTextBox{的容器,一般来说对它的常见操作有设|其Ҏ(gu),讄其布局{?
讄Ҏ(gu)代码:
setBorder(BorderFactory.createTitledBorder(title));
讄布局代码CZ:
setLayout(new GridLayout(4, 1));
add(nameInputPanel);
add(ageInputPanel);
add(titleInputPanel);
add(ButtonsPanel);
按钮cJButton
当我们需要向界面d按钮旉要用到JButtonc?以下是它的一些常用方?/p>
1.创徏Buttoncd?br /> JButton csvButton=new JButton("csv下蝲");
2.讄按钮的最大尺?最尺?首选尺?
Dimension dimension = new Dimension(80, 20);
csvButton.setMaximumSize(dimension);
csvButton.setMinimumSize(dimension);
csvButton.setPreferredSize(dimension);
单选框JRadioButton
我们需要单选按钮时需要用到JRadioButton,它的常用Ҏ(gu)如下:
1.创徏
JRadioButton xmlRadio=new JRadioButton("Xml",true);
JRadioButton db4oRadio=new JRadioButton("Db4o",false);
2.分组
ButtonGroup group = new ButtonGroup();
group.add(xmlRadio);
group.add(db4oRadio);
group.add(sqlRadio);
group.add(hibenateRadio);
3.取得单个JRadioButton是否被选择
boolean isSelected=db4oRadio.isSelected()
4.取得一lJRadioButton中被选择的单元的文字
for (Enumeration e=group.getElements(); e.hasMoreElements(); ) {
JRadioButton b = (JRadioButton)e.nextElement();
if (b.getModel() == group.getSelection()) {
return b.getText();
}
}
标签lgJLabel
JLabel是标{控?也是Swinglg中最单常用的一?
创徏JLabel:
JLabel label=new JLabel(“ABC");
修改标签文字
label.setText("DEF");
单行文本框JTextField
需要输入单行文字时我们可以用到JTextField,它的使用也很?
创徏:
JTextField textBox=new JTextField();
讄文本框文?
textBox.setText("ABC");
取得文本框文?
String text=textBox.getText();
复合框JComboBox
JComboBox是既能提供输入又能提供选择一的选择控g.
1) 创徏JComboBox
String[] items = {"item1", "item2"};
JComboBox editableCB = new JComboBox(items); editableCB.setEditable(true);
表格控gJTable
表格控g是相对复杂的Swing控g之一,使用也相对复?
1) 创徏表格控g
JTable table = new JTable();
2) 讄表格行高
table.setRowHeight(20);
3) 讄表格的行数和列数
DefaultTableModel tableModel = (DefaultTableModel) table
.getModel();
tableModel.setColumnCount(0);
tableModel.setRowCount(0);
4) l表格添加表?br /> String[] headers = {"姓名","q龄", "职务"};
for (int i = 0; i < headers.length; i++) {
tableModel.addColumn(headers[i]);
}
5) 向表格添加内?br />
public void fillTable(List<Member> members){
DefaultTableModel tableModel = (DefaultTableModel) table
.getModel();
tableModel.setRowCount(0);
for(Member member:members){
String[] arr=new String[5];
arr[0]=member.getName();
arr[1]=member.getAge();
arr[2]=member.getTitle();
tableModel.addRow(arr);
}
table.invalidate();
}
6) 取得表格内的内容
public List<Member> getShowMembers(){
List<Member> members=new ArrayList<Member>();
DefaultTableModel tableModel = (DefaultTableModel) table
.getModel();
int rowCount=tableModel.getRowCount();
for(int i=0;i<rowCount;i++){
Member member=new Member();
member.setName((String)tableModel.getValueAt(i, 0));
member.setAge((String)tableModel.getValueAt(i, 1));
member.setTitle((String)tableModel.getValueAt(i, 2));
members.add(member);
}
return members;
}