Action用于封装在程序的其他地方使用的功能,例如按钮,菜单和工具栏。下BeaconPanel图所示导出了一些操作,这些操作使在控制面板中轻松使用它们成为可能。为了限制实例的扩散,动作本身可以是类成员。作为练习,请更改controls为JToolBar或向菜单添加相同的操作。
JPanel controls = new JPanel();
controls.add(new JButton(beaconPanel.getFlashAction()));
controls.add(new JButton(beaconPanel.getOnAction()));
controls.add(new JButton(beaconPanel.getOffAction()));
图片
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Timer;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
/** @see http://stackoverflow.com/a/37063037/230513 */
public class Beacon {
private static class BeaconPanel extends JPanel {
private static final int N = 16;
private final Ellipse2D.Double ball = new Ellipse2D.Double();
private final Timer timer;
private final Color on;
private final Color off;
private final AbstractAction flashAction = new AbstractAction("Flash") {
@Override
public void actionPerformed(ActionEvent e) {
timer.restart();
}
};
private final AbstractAction onAction = new AbstractAction("On") {
@Override
public void actionPerformed(ActionEvent e) {
stop(on);
}
};
private final AbstractAction offAction = new AbstractAction("Off") {
@Override
public void actionPerformed(ActionEvent e) {
stop(off);
}
};
private Color currentColor;
public BeaconPanel(Color on, Color off) {
this.on = on;
this.off = off;
this.currentColor = on;
timer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
changeColors();
}
});
}
public void start() {
timer.start();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int x = getX() + N;
int y = getY() + N;
int w = getWidth() - 2 * N;
int h = getHeight() - 2 * N;
ball.setFrame(x, y, w, h);
g2.setColor(currentColor);
g2.fill(ball);
g2.setColor(Color.black);
g2.draw(ball);
}
private void changeColors() {
currentColor = currentColor == on ? off : on;
repaint();
}
private void stop(Color color) {
timer.stop();
currentColor = color;
repaint();
}
public Action getFlashAction() {
return flashAction;
}
public Action getOnAction() {
return onAction;
}
public Action getOffAction() {
return offAction;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(N * N, N * N);
}
}
public static void display() {
JFrame f = new JFrame("Beacon");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final BeaconPanel beaconPanel = new BeaconPanel(Color.orange, Color.orange.darker());
f.add(beaconPanel);
JPanel controls = new JPanel();
controls.add(new JButton(beaconPanel.getFlashAction()));
controls.add(new JButton(beaconPanel.getOnAction()));
controls.add(new JButton(beaconPanel.getOffAction()));
f.add(controls, BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
beaconPanel.start();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
Beacon.display();
}
});
}
}