gpt4 book ai didi

java - 一个类如何扩展 Thread 和 Gui?

转载 作者:行者123 更新时间:2023-11-29 06:32:43 25 4
gpt4 key购买 nike

我想创建一个有两个按钮的 GUI,这样当第一个按钮被点击时,它的颜色会在蓝色和白色之间来回变化,而当第二个按钮被点击时,它的颜色会在蓝色和白色之间来回变化。黄色和绿色。我希望两个按钮的颜色变化能够同时发生,所以我创建了两个类 Button1 和 Button2,它们都扩展了 Thread 类。但是,我现在遇到一个问题:在类Button1/Button2 中,您不能在主类(类Gui)中访问button1/button2。我希望 Button1/Button2 扩展 Thread 和 Gui,但这是不可能的; Java 不支持多重继承。 “public class Button1 extends Thread, Gui”和“public class Button1 extends Thread extends 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();
}
}
}

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();
}
}
}
}

Button2.java类似(略)

最佳答案

你问:

How can a class extend both Thread and Gui?

你的类不应该扩展两者。你的问题涉及几个问题,包括:

  • 您希望创建一个同时具有线程行为和图形用户界面行为的类,这强烈表明您正在创建一个“上帝”类,一个试图做太多事情的类。每个类(class)都应该有一个单一职责。
  • 您为什么要扩展 Thread?创建实现 Runnable 的类然后在线程中运行它要好得多。

您还声明:

However, I now encounter a problem: in the classes Button1/Button2, you can't access button1/button2 in the main class (class Gui). I want Button1/Button2 to extend both Thread and Gui, but this is not possible;

但这是对继承的误用。您不使用继承来“访问”另一个对象的字段,如果您尝试这样做,您的代码通常会编译但无法运行,因为访问的 gui 对象不是显示的对象。相反,您想使用组合——将一个对象的引用传递给另一个对象

您的代码的其他问题:

  • 您的线程代码不遵守 Swing 线程规则,因为您正试图从后台线程进行 Swing 调用。
  • 更好的方法是跳过线程和 Thread.sleep(...) 并使用 Swing 计时器,因为这将为您提供所需的延迟,并且会很好地尊重 Swing 线程。

例如,以下代码使用 AbstractActions(将它们视为功能强大的 ActionListeners)代替 ActionListeners,并使用 Swing Timer 来交换具有不同延迟时间的 JButtons 的文本。请注意,我不想发布完全解决您的任务的代码,而是向您展示我正在谈论的概念。

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);
}
}
}

关于java - 一个类如何扩展 Thread 和 Gui?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28908848/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com