1 java user-interface swing multithreading
我想用两个按钮创建一个GUI,这样当点击第一个按钮时,它的颜色会在蓝色和白色之间来回变换,当点击第二个按钮时,它的颜色会在黄色和绿色之间来回变换.我希望两个按钮的颜色变化能够同时发生,所以我创建了两个类Button1和Button2,它们都扩展了Thread类.但是,我现在遇到一个问题:在Button1/Button2类中,你无法访问主类(类Gui)中的button1/button2.我希望Button1/Button2扩展Thread和Gui,但这是不可能的; Java不支持多重继承.既没有"公共类Button1扩展Thread,Gui"也没有"公共类Button1扩展Thread扩展Gui"的作品.我该如何解决这个问题?
这是我的代码:
Gui.java:
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.io.*;
public class Gui implements ActionListener{
private JFrame frame;
private JButton button1;
private JButton button2;
private Button1 buttonone;
private Button2 buttontwo;
public Gui(){
frame = new JFrame("");
frame.setVisible(true);
frame.setSize(500,500);
buttonone = new Button1();
buttontwo = new Button2();
button1 = new JButton("button1");
button2 = new JButton("button2");
button1.addActionListener(this);
button2.addActionListener(this);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container container = frame.getContentPane();
container.setLayout(new FlowLayout());
container.add(button1);
container.add(button2);
}
public static void main(String[] args){
Gui gui = new Gui();
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == button1) {
buttonone.start();
}
if (e.getSource() == button2) {
buttontwo.start();
}
}
}
Run Code Online (Sandbox Code Playgroud)
Button1.java:
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.io.*;
public class Button1 extends Thread
{
public void run(){
while (true){
button1.setBackground(Color.blue); //here's where the problem is
try{
Thread.sleep(1000);
}
catch(InterruptedException e){
e.printStackTrace();
}
button1.setBackground(Color.white);
try{
Thread.sleep(1000);
}
catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
Button2.java类似(省略).
你问:
一个类如何扩展Thread和Gui?
你的类应该扩展既不.您的问题涉及几个问题,包括:
你也说:
但是,我现在遇到一个问题:在Button1/Button2类中,你无法访问主类(类Gui)中的button1/button2.我希望Button1/Button2扩展Thread和Gui,但这是不可能的;
但这是对继承的滥用.您不使用继承来"访问"另一个对象的字段,如果您尝试这样做,您的代码通常会编译但不起作用,因为访问的gui对象不是显示的对象.相反,你想使用组合 - 将一个对象的引用传递给另一个对象
您的代码的其他问题:
Thread.sleep(...)
使用Swing Timer,因为这会给你所需的延迟,并且也会很好地尊重Swing线程.例如,下面的代码使用AbstractActions(将它们视为超级动力的ActionListeners)代替ActionListeners,使用Swing Timer来交换JButton的文本,具有不同的延迟时间.请注意,我不想发布完全解决您的任务的代码,而是向您展示我正在谈论的概念.
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class ButtonFoo extends JPanel {
public ButtonFoo() {
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
setLayout(new GridLayout(1, 0, 5, 5));
add(new JButton(new SwapAction("Swap", "Fu", 1000)));
add(new JButton(new SwapAction("Snafu", "Fubar", 200)));
add(new JButton(new SwapAction("Goodbye", "Hello", 50)));
}
private static void createAndShowGui() {
JFrame frame = new JFrame("ButtonFoo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new ButtonFoo());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class SwapAction extends AbstractAction {
private String text1;
private String text2;
private int delay;
private Timer timer;
public SwapAction(String text1, String text2, int delay) {
super(text1);
this.text1 = text1;
this.text2 = text2;
this.delay = delay;
timer = new Timer(delay, new TimerListener());
}
@Override
public void actionPerformed(ActionEvent e) {
if (timer.isRunning()) {
timer.stop();
} else {
timer.start();
}
}
private class TimerListener implements ActionListener {
private boolean firstText = true;
@Override
public void actionPerformed(ActionEvent e) {
firstText = !firstText; //toggle boolean
String newName = firstText ? text1 : text2;
putValue(NAME, newName);
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
718 次 |
最近记录: |