我想制作一个简单的加法程序。在其中我想要将变量从Main_Window
传递到Second_Window
以进行添加,并且我希望多次在Second_Window
上获得结果。意味着如果我从Main_Window
多次传递变量以进行添加,那么结果应该在Second_Window
而不是第三和第四Window
。
我希望所有更改都应在Second_Window
上显示,而不是在打开时显示。
这些行是为从Main_Window
传递变量而编写的。
Second_Window s = new Second_Window(a,b);
s.setVisible(true);
答案 0 :(得分:1)
我将把我的previous answer代码作为基本代码提交给您的一个问题并添加一些功能:
首先,您需要创建第二个窗口的一个且仅一个实例,并且有一个方法可以更新发送给它的角度。
你如何做到这一点你可能会问自己,这很容易,在你的动作监听器中你创建实例,如果第二帧还没有创建,否则更新它。
private ActionListener listener = e -> {
if (e.getSource().equals(submitButton)) {
if (!frame.isVisible()) {
circle = new MyCircle((Integer) box1.getSelectedItem(), (Integer) box2.getSelectedItem());
frame.add(circle);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
} else {
circle.updateAngles((Integer) box1.getSelectedItem(), (Integer) box2.getSelectedItem());
}
}
};
如果关闭第二个窗口,之前的所有数据都将丢失,如果要保存该状态,请使用frame
可见性并初始化MyCircle
中的createAndShowGui()
实例下面代码中的方法。
接下来你需要跟踪你添加的所有角度,因为你可能需要List
并对其进行迭代,或者将其绘制到BufferedImage
,然后绘制JPanel
上的图片。对于此示例,我们将使用List
选项。
但是,对于这个例子,如果数据太多,可能无法显示,为了纠正这个问题,也可以使用JScrollPane
,但是我要把它留给你。
此示例也使整个程序仅在关闭主窗口时终止,但如果关闭第二个窗口则不会终止。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class RadiusDrawer {
private JFrame frame;
private JFrame mainFrame;
private int centerX = 50;
private int centerY = 50;
private int x1 = 0;
private int y1 = 0;
private int x2 = 0;
private int y2 = 0;
private int r = 100;
private JComboBox<Integer> box1;
private JComboBox<Integer> box2;
private JLabel label1;
private JLabel label2;
private JButton submitButton;
MyCircle circle;
private static final Integer[] ANGLES = new Integer[]{15, 30, 45, 60, 75, 90};
public static void main(String[] args) {
SwingUtilities.invokeLater(new RadiusDrawer()::createAndShowGui);
}
private void createAndShowGui() {
frame = new JFrame(getClass().getSimpleName());
mainFrame = new JFrame("Main Frame");
mainFrame.add(createMainWindow());
mainFrame.pack();
mainFrame.setVisible(true);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private ActionListener listener = e -> {
if (e.getSource().equals(submitButton)) {
if (!frame.isVisible()) {
circle = new MyCircle((Integer) box1.getSelectedItem(), (Integer) box2.getSelectedItem());
frame.add(circle);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
} else {
circle.updateAngles((Integer) box1.getSelectedItem(), (Integer) box2.getSelectedItem());
}
}
};
private JPanel createMainWindow() {
JPanel pane = new JPanel();
box1 = new JComboBox<>(ANGLES);
box2 = new JComboBox<>(ANGLES);
label1 = new JLabel("Angle 1");
label2 = new JLabel("Angle 2");
submitButton = new JButton("Submit");
submitButton.addActionListener(listener);
pane.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(20, 30, 20, 30);
pane.add(box1, gbc);
gbc.gridx = 1;
pane.add(box2, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
pane.add(label1, gbc);
gbc.gridx = 1;
pane.add(label2, gbc);
gbc.gridy = 2;
pane.add(submitButton, gbc);
return pane;
}
@SuppressWarnings("serial")
class MyCircle extends JPanel {
int cx = 0;
int cy = 0;
double lineX = 0;
double lineY = 0;
double roundedX = 0;
double roundedY = 0;
int angle1 = 0;
int angle2 = 0;
int angle1HistoryX = 15;
int angle2HistoryX = 150;
int angleHistoryY = 300;
int angleHistoryYGap = 20;
Color angle1Color = Color.BLUE;
Color angle2Color = Color.RED;
List <Integer> angle1History;
List <Integer> angle2History;
public MyCircle(int angle1, int angle2) {
this.angle1 = angle1;
this.angle2 = angle2;
angle1History = new ArrayList<>();
angle2History = new ArrayList<>();
angle1History.add(angle1);
angle2History.add(angle2);
calculateCoords();
calculateCenter();
}
private void updateAngles(int angle1, int angle2) {
this.angle1 = angle1;
this.angle2 = angle2;
angle1History.add(angle1);
angle2History.add(angle2);
calculateCoords();
this.revalidate();
this.repaint();
}
private void calculateCoords() {
x1 = (int) (r * Math.cos(Math.toRadians(angle1)));
y1 = (int) (r * Math.sin(Math.toRadians(angle1))) * -1;
x2 = (int) (r * Math.cos(Math.toRadians(angle2)));
y2 = (int) (r * Math.sin(Math.toRadians(angle2))) * -1;
}
private void calculateCenter() {
cx = centerX + r;
cy = centerY + r;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
drawCircle(g2d, centerX, centerY, r);
drawRadius(g2d);
drawHistory(g2d);
}
private void drawCircle(Graphics2D g2d, int x, int y, int r) {
g2d.setColor(Color.BLACK);
g2d.draw(new Ellipse2D.Double(x, y, r * 2, r * 2));
}
private void drawRadius(Graphics2D g2d) {
g2d.setColor(angle1Color);
g2d.draw(new Line2D.Double(cx, cy, cx + x1, cy + y1));
g2d.setColor(angle2Color);
g2d.draw(new Line2D.Double(cx, cy, cx + x2, cy + y2));
}
private void drawHistory(Graphics2D g2d) {
g2d.setColor(angle1Color);
g2d.drawString("Angle1", angle1HistoryX, angleHistoryY);
for (int i = 0; i < angle1History.size(); i++) {
g2d.drawString(angle1History.get(i).toString(), angle1HistoryX, angleHistoryY + (angleHistoryYGap * (i + 1)));
}
g2d.setColor(angle2Color);
g2d.drawString("Angle2", angle2HistoryX, angleHistoryY);
for (int i = 0; i < angle2History.size(); i++) {
g2d.drawString(angle2History.get(i).toString(), angle2HistoryX, angleHistoryY + (angleHistoryYGap * (i + 1)));
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 600);
}
}
}
就是这样!
答案 1 :(得分:0)
所以基本上你想让第二个窗口保持最大一个实例(如果永远不会点击主窗口中的按钮,则为零),要做到这一点,你需要保持对第二个窗口的静态引用,如果这个引用已经存在,您不创建新的,但要求现有的显示计算结果。
可能的方法:
对于主窗口中的提交按钮,您将收集所需参数的值,并调用第二个窗口类的静态方法。静态方法是属于类的方法,而不是对象。
btnSubmit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent aE) {
int azimuth = ...;
int elevation = ...;
SecondWindow.showResult(azimuth, elevation);
}
});
在第二个窗口类中,它保留此类的静态实例,最初为null。当调用showResult()时,它会检查实例是否尚不存在,然后创建一个新的第二个窗口并分配给静态引用。它要求实例计算并在UI中显示结果。
public class SecondWindow extends JFrame {
private static SecondWindow instance = null;
public static void showResult(int azimuth, int elevation) {
if (instance == null) {
instance = new SecondWindow();
}
instance.performShowResult(azimuth, elevation);
}
private void performShowResult(int azimuth, int elevation) {
// Display the result in UI.
}
}
最后要考虑的是,是否要在关闭实例时将其设置为null?如果是,请将此代码添加到第二个窗口构造函数:
public SecondWindow() {
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent aE) {
instance = null;
}
});
}
因此,再次调用showResult()时,将创建一个新的第二个窗口。
如果您认为第二个窗口的创建有点“沉重”,那么您可以保持第二个窗口关闭(因此不将实例设置为null),但确保在调用showResult()时显示它。像这样:
public static void showResult(int azimuth, int elevation) {
if (instance == null) {
instance = new SecondWindow();
} else if (instance.isShowing() == false) {
instance.setVisible(true);
}
instance.performShowResult(azimuth, elevation);
}