我试图创建一个小的GUI,它有2个JButtons和2个JPanels,每个JPanels上都有一些绘图动画。默认情况下,它必须显示第一个JPanel,通过单击第二个JButton我想看到第二个JPanel。所以:我创建了JFrame、Panel1和Panel2,在这里我绘制了我的动画,创建了Button1和Button2,并向它们添加了ActionListeners。我还有一个MainPanel,它有一个字段变量I。通过更改这个“I”,我的构造函数将Panel1(默认)或Panel2添加到MainPanel中(通过单击JButton2 I change I)。我把这个主面板加到我的框架上。所以我的问题是:在类MainPanel中我有refreshMehtml" target="_blank">方法,我应该在那里写什么来使我的GUI正常工作?多谢了。下面是我的代码:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class GuiTest {
public static void main(String[] args) {
JFrame f = new JFrame();
MainPanel myPanel = new MainPanel();
f.add(myPanel);
Button1 button1 = new Button1();
Button2 button2 = new Button2();
myPanel.add(button1);
myPanel.add(button2);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setVisible(true);
}
}
class MainPanel extends JPanel {
Panel1 p1 = new Panel1();
Panel2 p2 = new Panel2();
public int i = 1; //this is being changed later by clicking JButton
// I use this setter later in actionPerformed in order to change i
public void setI(int i) {
this.i = i;
}
MainPanel() {
if (i == 1) {
this.add(p1);
}
if (i == 2) {
this.add(p2);
}
}
public void refreshMe() {
// Need some help here:
// I don't know what should I write, how to make a repaint of myPanel?
System.out.println("just test, if the method refreshMe working by clicking some button");
}
}
class Panel1 extends JPanel {
public Panel1() {
this.setBackground(Color.BLUE);
// a lot of drawing stuff going on here
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
class Panel2 extends JPanel {
public Panel2() {
this.setBackground(Color.GREEN);
// a lot of drawing stuff going on here
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
class Button1 extends JButton {
MainPanel someObj1 = new MainPanel();
Button1() {
setText("Show Annimation A");
addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
someObj1.setI(1);
System.out.println("The variable i is now: " + someObj1.i);
someObj1.refreshMe();
}
});
}
}
class Button2 extends JButton {
MainPanel someObj2 = new MainPanel();
Button2() {
setText("Show Annimation B");
addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
someObj2.setI(2);
System.out.println("The variable i is now: " + someObj2.i);
someObj2.refreshMe();
}
});
}
}
为了反映添加/删除或调整可见容器上的组件后的更改,在添加/删除组件或调整组件的大小后,对容器实例调用revalidate()
和repaint()
。
虽然这在您的代码中不起作用,主要原因是在JButton类中,您重新创建了MainPanel
的新实例,而实际上2个JButtons
应该共享正在使用的单个实例(您可以将MainPanel实例传递给JButton
的构造函数,但除非添加自定义功能,否则不应该真正扩展JButton
):
class Button2 extends JButton {
MainPanel someObj2 = new MainPanel();//you create an instance of MainPanel which isnt even showing and than do changes on that, this way you will never see any of the changes
Button2() {
}
}
关于代码的其他一些建议:
>
不要不必要地扩展JButton
类,只需创建一个JButton
实例,就像您对JFrame
所做的那样,并调用JButton
实例的方法。
不要忘记通过SwingUtilities.invokelater(..)
块在Event Dispatch Thread
上创建/操作Swing组件,更多信息请阅读此处。
这里是您的代码修复(上面的建议等执行):
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame f = new JFrame();
final MainPanel myPanel = new MainPanel();
f.add(myPanel);
JButton button1 = new JButton("Show Animation A");
JButton button2 = new JButton("Show Animation B");
button1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
myPanel.setI(1);
System.out.println("The variable i is now: " + myPanel.i);
myPanel.refreshMe();
}
});
button2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
myPanel.setI(2);
System.out.println("The variable i is now: " + myPanel.i);
myPanel.refreshMe();
}
});
myPanel.add(button1);
myPanel.add(button2);
myPanel.checkPanel();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setVisible(true);
}
});
}
}
class MainPanel extends JPanel {
Panel1 p1 = new Panel1();
Panel2 p2 = new Panel2();
public int i = 1; //this is being changed later by clicking JButton
// I use this setter later in actionPerformed in order to change i
public void setI(int i) {
this.i = i;
}
public void refreshMe() {
checkPanel();
revalidate();
repaint();
// Need some help here:
// I don't know what should I write, how to make a repaint of myPanel?
System.out.println("just test, if the method refreshMe working by clicking some button");
}
public void checkPanel() {
if (i == 1) {
this.add(p1);
this.remove(p2);//or it will remain there as this is default flowlayout
} else if (i == 2) {
this.add(p2);
this.remove(p1);
}
}
}
class Panel1 extends JPanel {
public Panel1() {
this.setBackground(Color.BLUE);
// a lot of drawing stuff going on here
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
class Panel2 extends JPanel {
public Panel2() {
this.setBackground(Color.GREEN);
// a lot of drawing stuff going on here
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
不过我建议一些更简单的方法,幸运的是你有两个选择:
1)使用CardLayout
,它将允许您在单个JFrame
/容器上的多个组件之间翻转。
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
private final static String PANEL1 = "panel 1";
private final static String PANEL2 = "panel 2";
public Test() {
initComponents();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Test();
}
});
}
private void initComponents() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel1 = new JPanel();
panel1.add(new JLabel("Panel 1"));
JPanel panel2 = new JPanel();
panel2.add(new JLabel("Panel 2"));
//Create the panel that contains the "cards".
final JPanel cards = new JPanel(new CardLayout());
cards.add(panel1, PANEL1);
cards.add(panel2, PANEL2);
//create button to allow chnage to next card
JButton buttonNext = new JButton(">");
buttonNext.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
CardLayout cl = (CardLayout) (cards.getLayout());//get cards
cl.next(cards);
}
});
//create button to allow chnage to previous card
JButton buttonPrev = new JButton("<");
buttonPrev.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
CardLayout cl = (CardLayout) (cards.getLayout());//get cards
cl.previous(cards);
}
});
//create panel to hold buttons which will allow switching between cards
JPanel buttonPanel = new JPanel();
buttonPanel.add(buttonPrev);
buttonPanel.add(buttonNext);
frame.add(cards);
frame.add(buttonPanel, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
}
2)使用RemoveAll()
技术,即调用Frame.GetContentPane().RemoveAll()
,这将删除JFrame
上当前的所有组件,然后添加新内容,并调用Revalidate()
和Repaint()
(也可能希望在其中添加Pack()
)实例以反映更改。尽管Id推荐CardLayout
。
如果你们能回答这个问题,我会印象深刻的。基本上,我正在开发一个全堆栈的web应用程序,它包含以下三个组件: MongoDB文章集 用Java 8编写的后端 Javascript前端 程序流程应如下所示: 用户打开网页将文本输入到指定标题、作者、流派和内容的表单中。 当他们单击“addItem”按钮时,它应该将数据序列化为原始JSON并将其发送到我的addItemendpoint。 然后数据被清理,
问题内容: 按照标题,在Jenkins中,如何使用CLI将新的从属节点添加到构建集群中,或者如果没有CLI选项,是否可以使用另一种脚本化方法? 问题答案: 许多人使用Swarm插件来消除实际手动添加从站的需要。当然,您将需要编写swarm代理的安装脚本,但这应该很简单。
我正在开发一个发票系统,我想在每次单击添加新按钮时创建新字段。 每次都需要在下面的代码中添加字段。 字段需要显示在其各自的列下。 下面是我设置的按钮: 我知道这个网站上一定有答案,但我似乎找不到。 请注意,我是Java开发新手
问题内容: 我有个问题。我不知道如何通过单击JButton显示图像。 我有一个可以显示和隐藏图像的类: 我正在使用MVC,所以我想在我的控制器地图中使用JButton的代码,但是我不知道该怎么做。 单击按钮保持器时需要显示图像。 问题答案: 就像别人说的一样,总是用来显示图像。这样,很容易在需要时添加/删除它们,而不是绘画。此外,在您的代码中您正在重写,因为如果所讨论的组件具有一个,我们希望重写各
当用户单击时,我想将不同的添加到我的。 面板必须根据用户单击的按钮进行更改。这是我的代码的一部分: 我该怎么解决这个问题?
问题内容: 我是React的新手,对某种基本的东西感到困惑。 我需要在单击事件后呈现DOM之后将组件添加到DOM。 我最初的尝试如下,但是没有用。但这是我想尝试的最好的方法。(预先为将jQuery与React混合使用而道歉。) 希望我已经清楚需要做什么,希望您能帮助我获得适当的解决方案。 问题答案: 正如@Alex McMillan所提到的那样,使用state来指示应在dom中呈现的内容。 在下面