gpt4 book ai didi

java - 卷起框架后面板组件移动

转载 作者:行者123 更新时间:2023-12-02 10:12:46 25 4
gpt4 key购买 nike

我有这样的代码,我需要创建一些按钮来自定义正方形。它有效,但卷起框架后,文本字段在整个框架上移动,我不知道为什么。我的意思是,当我首先执行程序时,它位于我使用 setBounds() 方法提到的正确位置,但随后它位于正方形上方。那么我该如何修复它呢?

    import java.awt.*;
import java.awt.event.*;
import java.text.AttributedString;
import javax.swing.*;
import java.awt.font.TextAttribute;

public class Square extends JFrame implements ActionListener {

Button butt1 = new Button("Fill with yellow");
Button butt2 = new Button("Fill with red");
Button butt3 = new Button("Add label");
Button butt4 = new Button("");

Pan contentPane = new Pan();


public Square() {
super("Square");
this.setBounds(200, 100, 670, 400);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

this.getContentPane().add(contentPane);
contentPane.setBounds(0, 0, 670, 275);
contentPane.setBackground(Color.BLACK);

add(butt1);
butt1.setBounds(25, 300, 190, 25);
butt1.addActionListener(this);
add(butt2);
butt2.setBounds(235, 300, 190, 25);
butt2.addActionListener(this);
butt3.setBounds(440, 300, 190, 25);
butt3.addActionListener(this);
add(butt3);
add(butt4);

}

@Override
public void actionPerformed(ActionEvent e) {
Object o = e.getSource();
if (o == butt1) {
contentPane.draw(1);
}
else if (o == butt2) {
contentPane.draw(2);
}
else if (o == butt3) {
contentPane.draw(3);
}
}

public static void main(String[] args) {
Square w = new Square();
w.setVisible(true);
}
}

class Pan extends JPanel {
Graphics g;
Graphics2D g2;
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.GRAY);
g.drawRect(240, 70, 150, 150);
}

public void draw(int i) {

g = getGraphics();
super.paintComponent(g);
g2 = (Graphics2D) g.create();
switch(i) {
case 1: g2.setColor(Color.yellow);
g2.fillRect(240, 70, 150, 150);
break;
case 2: g2.setColor(Color.red);
g2.fillRect(240, 70, 150, 150);
break;
case 3:
g.setColor(Color.GRAY);
g.drawRect(240, 70, 150, 150);
JTextField text = new JTextField(25);
this.add(text);
Button add = new Button("Add");
add.setBounds(400, 230, 120, 25);
this.add(add);
text.setBounds(240, 230, 150, 25);

Font font = new Font("Veranda", Font.BOLD|Font.ITALIC, 24);
class AddButton extends JPanel implements ActionListener {
@Override
public void actionPerformed(ActionEvent ev) {
AttributedString label = new AttributedString(text.getText());
label.addAttribute(TextAttribute.FONT, font);
label.addAttribute(TextAttribute.FOREGROUND, Color.PINK);
g2.drawString(label.getIterator(), 240, 50);
}
}
AddButton listener = new AddButton();
add.addActionListener(listener);
break;
}

}
}

最佳答案

好吧,有很多核心问题和误解。

Swing 使用布局管理器。这可能是你们再次争论的第一件事之一。布局管理器根据各自的算法决定如何最好地定位组件。

首先查看 Laying Out Components Within a Container了解更多详细信息并充分利用它们。 GUI 是复杂且动态的事物,需要考虑许多因素来确定组件的大小和位置。

绘画。新开发人员面临的另一个问题是他们无法控制绘画系统。 Swing 使用被动渲染系统,这意味着它会在需要时进行绘制。

您可以通过调用repaint来提供何时应完成新绘制 channel 的提示,但由系统决定应绘制什么内容以及何时绘制。

g = getGraphics(); 在很多层面上都是一个坏主意。除了能够返回 null 之外,它只不过是最后一个绘制 channel 的快照,并且在新的绘制 channel 发生时将被丢弃。

在绘制 channel 之外调用 super.paintComponent(g); 也是一个坏主意。事实上,很少需要直接调用任何绘制方法。

这不是自定义绘画应该如何完成的。首先看一下Performing Custom PaintingPainting in AWT and Swing了解绘画的工作原理以及您应该如何使用它

此外,将重量级 (AWT) 和轻量级 (Swing) 组件混合在一起通常是一个坏主意,应尽可能避免。

示例...

所以,我将你的例子“破解”成“稍微”更合理的东西

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.font.TextAttribute;
import java.text.AttributedString;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

public class Square extends JFrame implements ActionListener {

JButton butt1 = new JButton("Fill with yellow");
JButton butt2 = new JButton("Fill with red");
JButton butt3 = new JButton("Add label");
JButton butt4 = new JButton("");

Pan contentPane = new Pan();

public Square() {
super("Square");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

this.getContentPane().add(contentPane);
contentPane.setBackground(Color.BLACK);

JPanel actions = new JPanel();
actions.setBorder(new EmptyBorder(10, 10, 10, 10));

actions.add(butt1);
butt1.addActionListener(this);
actions.add(butt2);
butt2.addActionListener(this);
butt3.addActionListener(this);
actions.add(butt3);
// actions.add(butt4);

add(actions, BorderLayout.SOUTH);

pack();
setLocationRelativeTo(null);
}

@Override
public void actionPerformed(ActionEvent e) {
Object o = e.getSource();
if (o == butt1) {
contentPane.draw(1);
} else if (o == butt2) {
contentPane.draw(2);
} else if (o == butt3) {
contentPane.draw(3);
}
}

public static void main(String[] args) {
Square w = new Square();
w.setVisible(true);
}
}

class Pan extends JPanel {

private int state = -1;
private String text = null;

public Pan() {
Font font = new Font("Veranda", Font.BOLD | Font.ITALIC, 24);
setFont(font);
setLayout(new GridBagLayout());
setBorder(new EmptyBorder(10, 10, 10, 10));
}

@Override
public Dimension getPreferredSize() {
return new Dimension(670, 275);
}

protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(Color.GRAY);
g2.drawRect(240, 70, 150, 150);
switch (state) {
case 1:
g2.setColor(Color.yellow);
g2.fillRect(240, 70, 150, 150);
break;
case 2:
g2.setColor(Color.red);
g2.fillRect(240, 70, 150, 150);
break;
case 3:
g.setColor(Color.GRAY);
g.drawRect(240, 70, 150, 150);
break;
}

if (text != null) {
AttributedString label = new AttributedString(text);
label.addAttribute(TextAttribute.FONT, getFont());
label.addAttribute(TextAttribute.FOREGROUND, Color.PINK);
g2.drawString(label.getIterator(), 240, 50);
}
}

public void draw(int i) {
switch (i) {
case 3:
JTextField textField = new JTextField(25);
JButton add = new JButton("Add");

GridBagConstraints gbc = new GridBagConstraints();

gbc.gridx = 0;
gbc.gridy = 0;
gbc.weighty = 1;
gbc.anchor = GridBagConstraints.SOUTH;

this.add(textField, gbc);
gbc.gridx++;
this.add(add, gbc);

add.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent ev) {
text = textField.getText();
remove(textField);
remove(add);

revalidate();
repaint();
}
});

revalidate();
repaint();

break;
}
state = i;
repaint();

}
}

Magic numbers

您的代码充满了通常所说的“魔数(Magic Number)”。这些值的含义未知。

运行代码并尝试调整窗口大小,您就会明白我的意思。相反,您应该依赖“已知”值,例如 getWidthgetHeight 来更好地确定应如何呈现输出

关于java - 卷起框架后面板组件移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54880739/

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