第6章 实用工具
Swing包括许多实用工具,本章将介绍这些实用工具。其中有些实用工具(如计时器和由SwingUtilties类提供的static方法)在Swing内部使用,而进度监视器和进度监视器流等其他的实用工具则不是内容使用的。使用Swing的开发人员可以使用本章介绍的所有实用工具。
6.1 计时器
例6-1 使用Swing计时器
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Test implements ActionListener {
private int seconds=1;
public Test() {
Timer oneSecondTimer = new Timer(1000, this);
Timer timerWithInitialDelay = new Timer(2000,
new TimerWithDelayListener());
Timer oneTimeTimer = new Timer(10000,
new OneTimeListener());
timerWithInitialDelay.setInitialDelay(5000);
oneTimeTimer.setRepeats(false);
oneSecondTimer.start();
timerWithInitialDelay.start();
oneTimeTimer.start();
}
public void actionPerformed(ActionEvent e) {
if(seconds == 0)
System.out.println("Time: " + seconds + " second");
else
System.out.println("Time: " + seconds + " seconds");
seconds++;
}
public static void main(String args[]) {
new Test();
while(true);
}
}
class TimerWithDelayListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.out.println("Timer with Delay Ringing");
}
}
class OneTimeListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.out.println("One Time Timer Ringing");
}
}
例6-2 重载构造计时器时所指定的延迟
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Test implements ActionListener {
public Test() {
Timer oneSecondTimer = new Timer(1000, this);
oneSecondTimer.setInitialDelay(10000);
oneSecondTimer.setRepeats(false);
oneSecondTimer.start();
}
public void actionPerformed(ActionEvent e) {
System.out.println("ring ...");
}
public static void main(String args[]) {
new Test();
while(true);
}
}
例6-3 计时器日志
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Test implements ActionListener {
public Test() {
Timer.setLogTimers(true);
Timer oneSecondTimer = new MyTimer(1000, this);
oneSecondTimer.start();
}
public void actionPerformed(ActionEvent e) {
System.out.println("ring ...");
}
public static void main(String args[]) {
new Test();
while(true);
}
}
class MyTimer extends Timer {
public MyTimer(int delay, ActionListener listener) {
super(delay, listener);
}
public String toString() {
return "MyTimer";
}
}
例6-4 与单个计时器相关联的多个动作监听器
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Test implements ActionListener {
private int seconds=1;
public Test() {
Timer oneSecondTimer = new Timer(1000, this);
oneSecondTimer.addActionListener(new SecondListener());
oneSecondTimer.addActionListener(new ThirdListener());
oneSecondTimer.start();
}
public void actionPerformed(ActionEvent e) {
if(seconds == 0)
System.out.println("Time: " + seconds + " second");
else
System.out.println("Time: " + seconds + " seconds");
seconds++;
}
public static void main(String args[]) {
new Test();
while(true);
}
}
class SecondListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.out.println("Second Listener");
}
}
class ThirdListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.out.println("Third Listener");
}
}
例6-5 合并计时器事件
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Test implements ActionListener {
private boolean firstRing = true;
private int ring = 1;
public Test() {
Timer.setLogTimers(true);
Timer oneSecondTimer = new Timer(1000, this);
// comment out the following line for colaescing
oneSecondTimer.setCoalesce(false);
System.out.println("Timer is coalescing: " +
oneSecondTimer.isCoalesce());
oneSecondTimer.start();
}
public void actionPerformed(ActionEvent e) {
System.out.println("ring #" + ring++);
if(firstRing) {
// simulate a time consuming operation by sleeping
// for 10 seconds ...
try {
Thread.currentThread().sleep(10000);
}
catch(InterruptedException ex) {
ex.printStackTrace();
}
firstRing = false;
}
}
public static void main(String args[]) {
new Test();
while(true);
}
}
6.2 事件监听器列表
6.3 Swing实用工具
例6-6 计算两个矩形之间的差集、交集和并集
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Test extends JApplet {
Rectangle r1 = new Rectangle(20,20,150,75);
Rectangle r2 = new Rectangle(100,40,100,150);
Rectangle destination;
public Test() {
destination = new Rectangle(r2);
// print out the intersection of r1 and r2 ...
System.out.println("Intersection: " +
SwingUtilities.computeIntersection(r1.x,r1.y,
r1.width,r1.height,destination));
System.out.println();
// print out the union of r1 and r2 ...
System.out.println("Union: " +
SwingUtilities.computeUnion(r1.x,r1.y,
r1.width,r1.height,destination));
System.out.println();
// print out the difference of r1 and r2 ...
Rectangle[] difference =
SwingUtilities.computeDifference(r1, r2);
System.out.println("Difference:");
for(int i=0; i < difference.length; ++i) {
System.out.println(difference[i]);
}
}
public void paint(Graphics g) {
g.setColor(Color.red);
g.fillRect(r1.x, r1.y, r1.width, r1.height);
g.setColor(Color.yellow);
g.fillRect(r2.x, r2.y, r2.width, r2.height);
}
}
<applet archive="s06_tu02.jar" code="Test.class" width="600" height="550"><param name="height" value="550">
<param name="archive" value="s06_tu02.jar">
<param name="width" value="600">
<param name="code" value="Test.class">
<param name="codeBase" value="http://www.web.nyist.net/~rf/gui/"></applet>
图6-2 转换坐标系统
例6-7 转换鼠标坐标
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Test extends JApplet {
private Point lastScreenPt = null;
private final Container contentPane = getContentPane();
private PanelWithString
outer = new PanelWithString(Color.orange),
inner = new PanelWithString(Color.red),
innermost = new PanelWithString(Color.yellow);
public Test() {
Font font = new Font("Times-Roman", Font.ITALIC, 26);
contentPane.setLayout(new OverlayLayout(contentPane));
contentPane.add(innermost);
contentPane.add(inner);
contentPane.add(outer);
innermost.setMaximumSize(new Dimension(350,50));
inner.setMaximumSize(new Dimension(450,200));
outer.setMaximumSize(new Dimension(550,400));
setFont(font);
innermost.setFont(font);
inner.setFont(font);
outer.setFont(font);
contentPane.addMouseMotionListener(
new MouseMotionAdapter() {
public void mouseMoved(MouseEvent e) {
Point pt = e.getPoint();
outer.setString(SwingUtilities.convertPoint(
contentPane, pt, outer).toString());
inner.setString(SwingUtilities.convertPoint(
contentPane, pt, inner).toString());
innermost.setString(SwingUtilities.convertPoint(
contentPane, pt, innermost).toString());
SwingUtilities.convertPointToScreen(
pt, contentPane);
lastScreenPt = pt;
repaint();
}
});
}
public void paint(Graphics g) {
super.paint(g);
if(lastScreenPt != null) {
String s = new String("Screen: " + lastScreenPt);
g.setColor(getForeground());
g.drawString(s,10,g.getFontMetrics().getHeight());
SwingUtilities.convertPointFromScreen(lastScreenPt,
contentPane);
s = "Content Pane: " + lastScreenPt;
g.drawString(s,10,g.getFontMetrics().getHeight()*2);
}
else {
g.setColor(getForeground());
g.drawString("MOVE THE MOUSE IN HERE",10,
g.getFontMetrics().getHeight());
}
}
}
class PanelWithString extends JPanel {
String s;
Color color;
public PanelWithString(Color color) {
this.color = color;
}
public void setString(String s) {
this.s = s;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Dimension size = getSize();
g.setColor(color);
g.fillRect(0,0,size.width,size.height);
if(s != null) {
g.setColor(getForeground());
g.drawString(s,10,g.getFontMetrics().getHeight());
}
}
}
6.4 Swing常量
6.5 Borlayout和Box类
6.5.1 BoxLayout类
<applet archive="s06_tu03.jar" code="Test.class" width="400" height="250"><param name="height" value="250">
<param name="archive" value="s06_tu03.jar">
<param name="width" value="400">
<param name="code" value="Test.class">
<param name="codeBase" value="http://www.web.nyist.net/~rf/gui/"></applet>
图6-3 两个使用BoxLayout的容器
例6-8 使用BoxLayout
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Test extends JApplet {
public Test() {
Container contentPane = getContentPane();
ContainerWithBoxLayout yaxis =
new ContainerWithBoxLayout(BoxLayout.Y_AXIS);
ContainerWithBoxLayout xaxis =
new ContainerWithBoxLayout(BoxLayout.X_AXIS);
contentPane.setLayout(new FlowLayout());
xaxis.add(new JButton(new ImageIcon("reach.gif")));
xaxis.add(new JButton(new ImageIcon("punch.gif")));
xaxis.add(new JButton(new ImageIcon("open_hand.gif")));
yaxis.add(new JButton(new ImageIcon("ladybug.gif")));
yaxis.add(new JButton(new ImageIcon("crab.gif")));
yaxis.add(new JButton(new ImageIcon("frog.gif")));
yaxis.add(new JButton(new ImageIcon("snail.gif")));
contentPane.add(xaxis);
contentPane.add(yaxis);
}
}
class ContainerWithBoxLayout extends JPanel {
public ContainerWithBoxLayout(int orientation) {
setLayout(new BoxLayout(this, orientation));
}
}
6.5.2 Box类
例6-9 使用水平和垂直的膨胀体
6.6 进度监视器
6.6.1 ProgressMonitor
图6-5 使用一个进度监视器(注:此为一可点击执行的.jar文件,但需要下载到你的电脑上方可点击执行)
例6-10 使用一个进度监视器
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
public class Test extends JFrame {
private JButton readButton = new JButton("read file");
private BufferedInputStream in;
private ProgressMonitor pm;
private String fileName = "Test.java";
public Test() {
final Container contentPane = getContentPane();
contentPane.setLayout(new FlowLayout());
contentPane.add(readButton);
readButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
in = new BufferedInputStream(
new FileInputStream(fileName));
pm = new ProgressMonitor(contentPane,
"Reading File:",
fileName,
0, in.available());
}
catch(FileNotFoundException fnfx) {
fnfx.printStackTrace();
}
catch(IOException iox) {
iox.printStackTrace();
}
ReadThread t = new ReadThread();
t.start();
}
});
}
class ReadThread extends Thread {
int i, cnt=0;
String s;
public void run() {
try {
readButton.setEnabled(false);
while(!pm.isCanceled() && (i = in.read()) != -1) {
try {
Thread.currentThread().sleep(25);
}
catch(InterruptedException ex) {
ex.printStackTrace();
}
System.out.print((char)i);
SwingUtilities.invokeLater(new Runnable(){
public void run() {
pm.setProgress(++cnt);
}
});
}
if(pm.isCanceled())
JOptionPane.showMessageDialog(
Test.this,
"Operation Canceled!",
"Cancellation",
JOptionPane.ERROR_MESSAGE);
}
catch(IOException ex) {
ex.printStackTrace();
}
finally {
try {
in.close();
}
catch(IOException ex2) {
ex2.printStackTrace();
}
}
readButton.setEnabled(true);
}
}
public static void main(String args[]) {
GJApp.launch(new Test(),
"Using Progress Monitors",300,300,450,300);
}
}
class GJApp extends WindowAdapter {
static private JPanel statusArea = new JPanel();
static private JLabel status = new JLabel(" ");
static private ResourceBundle resources;
public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h) {
launch(f,title,x,y,w,h,null);
}
public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h,
String propertiesFilename) {
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);
statusArea.setBorder(BorderFactory.createEtchedBorder());
statusArea.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
statusArea.add(status);
status.setHorizontalAlignment(JLabel.LEFT);
f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);
if(propertiesFilename != null) {
resources = ResourceBundle.getBundle(
propertiesFilename, Locale.getDefault());
}
f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
static public JPanel getStatusArea() {
return statusArea;
}
static public void showStatus(String s) {
status.setText(s);
}
static Object getResource(String key) {
if(resources != null) {
return resources.getString(key);
}
return null;
}
}
6.6.2 PropressMonitorInputStream
例6-11 使用ProgressMonitorInputStream
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
public class Test extends JFrame {
private ProgressMonitorInputStream in;
private JButton readButton = new JButton("read file");
public Test() {
final Container contentPane = getContentPane();
final String fileName = "Test.java";
contentPane.setLayout(new FlowLayout());
contentPane.add(readButton);
readButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
in = new ProgressMonitorInputStream(
contentPane,
"Reading " + fileName,
new FileInputStream(fileName));
}
catch(FileNotFoundException ex) {
ex.printStackTrace();
}
ReadThread t = new ReadThread();
readButton.setEnabled(false);
t.start();
}
});
}
class ReadThread extends Thread {
public void run() {
int i;
try {
while((i = in.read()) != -1) {
System.out.print((char)i);
try {
Thread.currentThread().sleep(10);
}
catch(Exception ex) {
ex.printStackTrace();
}
}
in.close();
}
catch(IOException ex) {
JOptionPane.showMessageDialog(
Test.this,
"Operation Canceled!",
"Cancellation",
JOptionPane.ERROR_MESSAGE);
}
readButton.setEnabled(true);
}
}
public static void main(String args[]) {
GJApp.launch(new Test(),
"Using ProgressMonitorInputStream",
300,300,450,300);
}
}
class GJApp extends WindowAdapter {
static private JPanel statusArea = new JPanel();
static private JLabel status = new JLabel(" ");
static private ResourceBundle resources;
public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h) {
launch(f,title,x,y,w,h,null);
}
public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h,
String propertiesFilename) {
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);
statusArea.setBorder(BorderFactory.createEtchedBorder());
statusArea.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
statusArea.add(status);
status.setHorizontalAlignment(JLabel.LEFT);
f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);
if(propertiesFilename != null) {
resources = ResourceBundle.getBundle(
propertiesFilename, Locale.getDefault());
}
f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
static public JPanel getStatusArea() {
return statusArea;
}
static public void showStatus(String s) {
status.setText(s);
}
static Object getResource(String key) {
if(resources != null) {
return resources.getString(key);
}
return null;
}
}
6.7 撤消/重复
6.7.1一个简单的撤消/重复样例
例6-12 一个简单的撤消/重复样例
import javax.swing.*;
import javax.swing.undo.*;
import java.awt.*;
import java.awt.event.*;
public class Test extends JApplet {
private JPanel colorPanel = new JPanel();
private BackgroundColorEdit undo = new BackgroundColorEdit();
private Color oldColor;
public void init() {
colorPanel.setBorder(
BorderFactory.createTitledBorder(
"Change color and subsequently undo " +
"from the Edit menu"));
makeMenuBar();
getContentPane().add(colorPanel, BorderLayout.CENTER);
}
private void makeMenuBar() {
JMenuBar menuBar = new JMenuBar();
JMenu editMenu = new JMenu("Edit");
editMenu.add(new SetColorAction());
editMenu.add(new UndoAction());
menuBar.add(editMenu);
setJMenuBar(menuBar);
}
class SetColorAction extends AbstractAction {
public SetColorAction() {
super("Set color ...");
}
public void actionPerformed(ActionEvent e) {
Color color = JColorChooser.showDialog(
Test.this, // parent component
"Pick A Color", // dialog title
null); // initial color
if(color != null) {
oldColor = colorPanel.getBackground();
colorPanel.setBackground(color);
}
}
}
class UndoAction extends AbstractAction {
public UndoAction() {
putValue(Action.NAME, undo.getUndoPresentationName());
}
public void actionPerformed(ActionEvent e) {
String name = (String)getValue(Action.NAME);
boolean isUndo = name.equals(
undo.getUndoPresentationName());
if(isUndo) {
undo.undo();
putValue(Action.NAME,
undo.getRedoPresentationName());
}
else {
undo.redo();
putValue(Action.NAME,
undo.getUndoPresentationName());
}
}
}
class BackgroundColorEdit extends AbstractUndoableEdit {
public void undo() throws CannotUndoException {
super.undo();
toggleColor();
}
public void redo() throws CannotRedoException {
super.redo();
toggleColor();
}
public String getUndoPresentationName() {
return "Undo";
}
public String getRedoPresentationName() {
return "Redo";
}
private void toggleColor() {
Color color = colorPanel.getBackground();
colorPanel.setBackground(oldColor);
oldColor = color;
}
}
}
6.7.2 UndoableEditSupport
例6-13 使用UndoableEditSupport
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.undo.*;
import java.awt.*;
import java.awt.event.*;
public class Test extends JApplet {
private ColorPanel colorPanel = new ColorPanel();
private UndoAction undoAction = new UndoAction();
public void init() {
colorPanel.setBorder(
BorderFactory.createTitledBorder(
"Change color and subsequently undo " +
"from the Edit menu"));
makeMenuBar();
colorPanel.addUndoableEditListener(undoAction);
getContentPane().add(colorPanel, BorderLayout.CENTER);
}
private void makeMenuBar() {
JMenuBar menuBar = new JMenuBar();
JMenu editMenu = new JMenu("Edit");
editMenu.add(new SetColorAction());
editMenu.add(undoAction);
menuBar.add(editMenu);
setJMenuBar(menuBar);
}
class UndoAction extends AbstractAction
implements UndoableEditListener {
UndoableEdit lastEdit;
public UndoAction() {
putValue(Action.NAME, "Undo");
setEnabled(false);
}
public void actionPerformed(ActionEvent e) {
String name = (String)getValue(Action.NAME);
boolean isUndo = name.equals(
lastEdit.getUndoPresentationName());
if(isUndo) {
lastEdit.undo();
putValue(Action.NAME,
lastEdit.getRedoPresentationName());
}
else {
lastEdit.redo();
putValue(Action.NAME,
lastEdit.getUndoPresentationName());
}
}
public void undoableEditHappened(UndoableEditEvent e) {
lastEdit = e.getEdit();
putValue(Action.NAME,
lastEdit.getUndoPresentationName());
if(lastEdit.canUndo())
setEnabled(true);
}
}
class SetColorAction extends AbstractAction {
public SetColorAction() {
super("Set color ...");
}
public void actionPerformed(ActionEvent e) {
Color color = JColorChooser.showDialog(
Test.this, // parent component
"Pick A Color", // dialog title
null); // initial color
if(color != null) {
colorPanel.setBackground(color);
}
}
}
}
class ColorPanel extends JPanel {
UndoableEditSupport support;
BackgroundColorEdit edit = new BackgroundColorEdit();
Color oldColor;
public void addUndoableEditListener(
UndoableEditListener l) {
support.addUndoableEditListener(l);
}
public void removeUndoableEditListener(
UndoableEditListener l) {
support.removeUndoableEditListener(l);
}
public void setBackground(Color color) {
oldColor = getBackground();
super.setBackground(color);
if(support == null)
support = new UndoableEditSupport();
support.postEdit(edit);
}
class BackgroundColorEdit extends AbstractUndoableEdit {
public void undo() throws CannotUndoException {
super.undo();
toggleColor();
}
public void redo() throws CannotRedoException {
super.redo();
toggleColor();
}
public String getUndoPresentationName() {
return "Undo Background Color Change";
}
public String getRedoPresentationName() {
return "Redo Background Color Change";
}
private void toggleColor() {
Color color = getBackground();
setBackground(oldColor);
oldColor = color;
}
}
}
6.7.3组合编辑
例6-14 使用组合编辑
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.undo.*;
import java.awt.*;
import java.awt.event.*;
public class Test extends JApplet {
private UndoableList list = new UndoableList();
private JScrollPane scrollPane = new JScrollPane(list);
private JButton addButton = new JButton("Add Item"),
endButton = new JButton("End"),
undoButton = new JButton("Undo");
private UndoAction undoAction = new UndoAction();
private CompoundEdit compoundEdit = new CompoundEdit();
private int cnt=0;
public void init() {
Container contentPane = getContentPane();
contentPane.setLayout(new FlowLayout());
contentPane.add(addButton);
contentPane.add(endButton);
contentPane.add(undoButton);
contentPane.add(scrollPane);
scrollPane.setPreferredSize(new Dimension(150,150));
list.addUndoableEditListener(undoAction);
endButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
compoundEdit.end();
updateButtonsEnabledState();
}
});
addButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
list.undoableAdd("item #" + cnt++);
updateButtonsEnabledState();
}
});
undoButton.addActionListener(undoAction);
endButton.setEnabled(false);
undoButton.setEnabled(false);
}
private void updateButtonsEnabledState() {
boolean inProgress = compoundEdit.isInProgress();
endButton.setEnabled(inProgress);
addButton.setEnabled(inProgress);
if(undoButton.getText().equals("Undo"))
undoButton.setEnabled(compoundEdit.canUndo());
else
undoButton.setEnabled(compoundEdit.canRedo());
}
class UndoAction extends AbstractAction
implements UndoableEditListener {
public UndoAction() {
putValue(Action.NAME, "Undo");
}
public void actionPerformed(ActionEvent e) {
String name = undoButton.getText();
boolean isUndo = name.equals("Undo");
if(isUndo) compoundEdit.undo();
else compoundEdit.redo();
undoButton.setText(isUndo ? "Redo" : "Undo");
}
public void undoableEditHappened(UndoableEditEvent e) {
UndoableEdit edit = e.getEdit();
compoundEdit.addEdit(edit);
endButton.setEnabled(true);
}
}
}
class UndoableList extends JList {
UndoableEditSupport support = new UndoableEditSupport();
DefaultListModel model;
public UndoableList() {
setModel(model = new DefaultListModel());
}
public void addUndoableEditListener(UndoableEditListener l) {
support.addUndoableEditListener(l);
}
public void removeUndoableEditListener(
UndoableEditListener l) {
support.removeUndoableEditListener(l);
}
public void undoableAdd(Object s) {
model.addElement(s);
support.postEdit(new AddItemEdit());
}
class AddItemEdit extends AbstractUndoableEdit {
Object lastItemAdded;
public void undo() throws CannotUndoException {
super.undo();
lastItemAdded = model.getElementAt(model.getSize()-1);
model.removeElement(lastItemAdded);
}
public void redo() throws CannotRedoException {
super.redo();
model.addElement(lastItemAdded);
}
}
}
6.7.4 UndoManager
6.7.5状态编辑
例6-15 使用状态编辑
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.undo.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class Test extends JApplet {
private TextFieldPanel panel = new TextFieldPanel();
private StateEdit stateEdit;
private JButton startButton = new JButton("Start Edit"),
endButton = new JButton("End Edit"),
undoButton = new JButton("Undo");
public void init() {
Container contentPane = getContentPane();
contentPane.setLayout(new FlowLayout());
contentPane.add(startButton);
contentPane.add(endButton);
contentPane.add(undoButton);
contentPane.add(panel);
endButton.setEnabled(false);
undoButton.setEnabled(false);
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
stateEdit = new StateEdit(panel);
endButton.setEnabled(true);
startButton.setEnabled(false);
}
});
endButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
stateEdit.end();
undoButton.setEnabled(true);
endButton.setEnabled(false);
}
});
undoButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String name = undoButton.getText();
boolean isUndo = name.equals("Undo");
if(isUndo) stateEdit.undo();
else stateEdit.redo();
undoButton.setText(isUndo ? "Redo" : "Undo");
}
});
}
}
class TextFieldPanel extends JPanel implements StateEditable {
JTextField[] fields = new JTextField[] {
new JTextField("text field 1"),
new JTextField("text field 2"),
new JTextField("text field 3"),
new JTextField("text field 4"),
};
public TextFieldPanel() {
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
for(int i=0; i < fields.length; ++i)
add(fields[i]);
}
public void storeState(Hashtable hashtable) {
for(int i=0; i < fields.length; ++i)
hashtable.put(fields[i], fields[i].getText());
}
public void restoreState(Hashtable hashtable) {
Enumeration keys = hashtable.keys();
while(keys.hasMoreElements()) {
JTextField field = (JTextField)keys.nextElement();
field.setText((String)hashtable.get(field));
}
}
}
6.8 本章回顾
相关推荐
Java 2图形设计卷Ⅱ:SWING 是一本专注于Java Swing技术的专业书籍,它深入探讨了如何使用Java的GUI(图形用户界面)库来构建功能丰富的桌面应用。Swing是Java AWT(Abstract Window Toolkit)的扩展,提供了更为...
Java 2 图形设计卷1 AWT 是一本深入探讨Java图形用户界面(GUI)编程的书籍,主要聚焦在Abstract Window Toolkit(AWT)这个Java早期的GUI库上。AWT是Java平台的基础部分,提供了创建窗口、按钮、文本框等基本组件的...
本资料“java图形设计卷2swing”深入探讨了Swing组件、布局管理、事件处理以及如何创建美观且功能丰富的用户界面。 1. **Swing组件**:Swing 提供了丰富的组件库,如按钮(JButton)、文本框(JTextField)、列表(JList...
第6章 时间、日期和数字 第7章 AWT组件及事件处理 第8章 建立对话框 第9章 Java多线程机制 第10章 输入输出流 第11章 Java网络的基本知识 第12章 JavaApplet基础 第13章 常见数据结构的Java实现 第14章图形与图像 第...
在Java编程环境中,Swing库是用于构建图形用户界面(GUI)的重要工具,它提供了丰富的组件和功能,使得开发者能够创建交互性强、功能完备的应用程序。 1. **Java Swing基础**: - Swing是Java AWT(Abstract ...
2. 第六章可能介绍了事件处理和监听器,这是让GUI具有交互性的关键。 3. 第二十章可能涉及高级主题,如自定义组件或者Swing的高级特性。 4. 第十三章和第十四章可能涵盖了特定的GUI设计技巧或特定组件的深入使用。 5...
7. **Swing Utilities**:Swing还提供了一些实用工具类,如SwingUtilities,用于线程同步、组件定位、事件调度等,帮助开发者简化任务。 在实际开发中,`swing插件`可能指的是特定的第三方库或工具,它们进一步扩展...
总的来说,Swing-explorer是Java Swing开发者的一款实用工具,它简化了GUI开发过程,提高了开发效率,通过可视化的方式帮助开发者理解和调试Swing应用程序。对于那些经常处理Swing项目的开发者来说,这是一款不可或...
- **Java的Swing编程**:Swing是Java的一个图形用户界面(GUI)工具包,用于构建桌面应用程序,提供了丰富的组件和布局管理器。 - **Java的JDBC编程**:JDBC是Java访问数据库的标准API,用于与各种类型的数据库...
Java语言程序设计中的第十二章主要探讨了图形用户界面(GUI)的基础知识,特别是使用Java进行GUI编程。GUI是用户与计算机系统交互的一种直观方式,Java提供了强大的API来支持这一功能,包括AWT(Abstract Window ...
Java Swing 是Java GUI(图形用户界面)库的一部分,它提供了丰富的组件和功能,用于构建桌面应用程序。本资源“java-swing 实例集合及其源码”包含了一系列基于Swing的示例应用,包括中国象棋、蜘蛛纸牌、网络...
【Java Swing GUI组件技术】是Java程序设计中用于构建图形用户界面的重要工具。在这个课程设计实训项目中,学生被要求使用Java Swing库来创建一个课程选课系统的图形用户界面(GUI)。具体来说,主要涉及以下几个...
Java Swing 是Java平台上的一个图形用户界面(GUI)工具包,它是Java Foundation Classes (JFC) 的一部分。这个工具包允许开发者创建丰富的桌面应用程序,提供了一系列组件,如按钮、文本框、滚动条等,用于构建复杂...
Java Swing 是Java GUI(图形用户界面)开发的一个重要库,它是Java AWT(Abstract Window Toolkit)的扩展,提供了更为丰富的组件和更强大的功能。在这个“使用JavaSwing重写的美化版窗口模板”中,我们可以深入...
通过本书第六章的实例和练习题,学习者将能深入理解如何使用Swing构建功能丰富的GUI应用程序,包括如何组合组件、设计布局、处理事件、以及定制组件外观等。这些实践将有助于提升Java GUI编程的能力,为开发出更具...
在本章节"JAVA语言程序设计-第十二章 高级用户界面GUI设计"中,我们将深入探讨Java如何创建美观且功能丰富的图形用户界面(GUI)。GUI是计算机软件中与用户进行交互的一种方式,使得非程序员也能轻松操作应用程序。...
【创建Java图形绘制应用程序】 在本教程中,我们将学习如何使用Java编程语言和Java Swing库创建一个图形绘制应用程序。这个应用程序将提供用户绘制、编辑和保存图形的功能,涵盖以下核心知识点: 1. **Java Swing...
Java Swing 是Java GUI(图形用户界面)库的一部分,用于创建桌面应用程序。在这个特定的问题中,我们需要使用Swing来创建一个图形界面,展示用户输入文件中字母的频率统计,以柱状图的形式呈现。以下是实现这一功能...
Swing是Java平台上用于构建图形用户界面(GUI)的一个关键工具包,它提供了丰富的组件和功能,使得开发者可以创建出美观且功能强大的桌面应用。 本书主要涵盖以下几个核心知识点: 1. **Swing基础**:介绍Swing的...