我几乎让repaint()Jcomponent正常工作。我让它工作,然后尝试进行绝对定位,现在它不起作用。
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
public class DDHGenericFrame {
private static final long serialVersionUID = 1L;
DDHGenericPanel d = new DDHGenericPanel();
//DDHCircleOne o = new DDHCircleOne();
public DDHGenericFrame() {
initUI();
}
public final void initUI() {
JFrame frame = new JFrame("AbsoluteLayoutDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Draw Circle");
frame.setBackground(Color.green);
frame.setLayout(null);
frame.setSize(300,425);
frame.add(d);
// frame.add(o);//didn't work neither
frame.setVisible(true);
}
public static void main(String[] args) {
DDHGenericFrame ex = new DDHGenericFrame();
}
}
第2类:(这是我试图设置的JComponent)
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JComponent;
public class DDHTestDraw extends JComponent {
public DDHTestDraw () {
settPreferredSize();
}
public void settPreferredSize() {
Dimension d = new Dimension(25,25);
setPreferredSize(d);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString("Text",20,20);
}
}
我将我的组件添加到Container,然后将容器添加到JPanel,然后将JPanel添加到JFrame。我认为这应该有效。我有一个首选大小。我让它工作一次,现在它不起作用。
我希望能够制作一个圆形的组件。我希望能够在Jframe上的任何位置绘制该圆,然后我希望该圆能够基于一定的时间长度移动。我打算制作一个圆圈从顶部掉落然后掉到底部的游戏。当我开始工作时,我确实将圆圈写入了JPanel,这是一段复杂的代码。但我不得不回到编写单个图形词的简单方法。
答案 0 :(得分:2)
修改强>
您的意见/我的回复:
当你说从不使用绝对布局时,我工作的公司总是只使用绝对布局。
有时它很有用,但不适用于创建典型的组件填充GUI。否则,GUI变得非常难以修改和维护。
当你的意思是一个逻辑类时,你指的是一个只创建一个圆的类。
是的,它包含该圈子的所有必要属性,例如颜色,位置,移动等。
然后Jpanel将绘制每个圆圈。
是。我想象绘图JPanel有ArrayList<MyCircle>
个,而paintComponent方法通过这个List迭代。
当你说Size这是JComponent中的属性时。
我认为它是Component,JComponent的父级的属性。如果使用null布局,则所有组件必须指定其大小和位置。否则,组件默认为[0,0]的位置和[0,0]的大小。
修改2
public Dimension Size(int a, int b) { Dimension d = new Dimension(); d.width = a; d.height = b; return d; }
这是我用于首选大小的代码。我迷失了为什么这不起作用。
此代码对Component / JComponent的size或preferredSize属性没有影响。它不会让我感到惊讶,它对你没有帮助。您必须覆盖getSize()
或getPreferredSize()
或明确调用setSize(...)
或getPreferredSize(...)
才能更改属性的状态。
我将尝试使用不同的布局管理器,但是我会看到一个布局管理器或另一个布局管理器之间的区别。
我不知道如何解释这个。
编辑3
你说:
我在一家公司工作,我们一直使用绝对布局。如果绝对布局不如BorderLayout()那么好。对我而言,BorderLayout()更难实现。或者是您使用带有BorderLayout的Jframe(),然后将Jpanel插入已经存在且已经是BorderLayout()的现有位置。我总是难以在与BorderLayout()不同的布局中使我的错位和位置正确。你能发布一个比
更容易使用的例子吗?
我猜你想要一个使用布局管理器比使用绝对定位更容易的例子。
我们以一个非常简单的计算器为例,一个带有数字输入和简单操作的按钮。此示例再次是非常基本,并且不起作用,但用于说明布局的使用。我可以轻松地将我的按钮放在GridLayout中 - 使用JPanel,然后将该按钮JPanel放入BorderLayout-使用边界的Layout.CENTER位置使用JPanel,显示,放置在BorderLayout.PAGE_START的相同BorderLayout-JPanel中位置:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.*;
public class CalcEg {
private static final float BTN_FONT_SIZE = 20f;
private static final String[][] BTN_LABELS = {
{"7", "8", "9", "-"},
{"4", "5", "6", "+"},
{"1", "2", "3", "/"},
{"0", ".", " ", "="}
};
private static final int GAP = 4;
private JPanel mainPanel = new JPanel(new BorderLayout(GAP, GAP));
private JPanel buttonPanel = new JPanel();
private JTextField display = new JTextField();
public CalcEg() {
int rows = BTN_LABELS.length;
int cols = BTN_LABELS[0].length;
buttonPanel.setLayout(new GridLayout(rows, cols, GAP, GAP));
for (String[] btnLabelRow : BTN_LABELS) {
for (String btnLabel : btnLabelRow) {
if (btnLabel.trim().isEmpty()) {
buttonPanel.add(new JLabel());
} else {
JButton btn = createButton(btnLabel);
buttonPanel.add(btn);
}
}
}
display.setFont(display.getFont().deriveFont(BTN_FONT_SIZE));
display.setEditable(false);
display.setFocusable(false);
display.setBackground(Color.white);
mainPanel.setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
mainPanel.add(buttonPanel, BorderLayout.CENTER);
mainPanel.add(display, BorderLayout.PAGE_START);
}
private JButton createButton(String btnLabel) {
JButton button = new JButton(btnLabel);
button.setFont(button.getFont().deriveFont(BTN_FONT_SIZE));
return button;
}
public JComponent getMainComponent() {
return mainPanel;
}
private static void createAndShowGui() {
CalcEg mainPanel = new CalcEg();
JFrame frame = new JFrame("CalcEg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel.getMainComponent());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
这将导致计算器看起来像这样:
现在,确定你可以说你可以使用null布局和setbounds(...)
生成这个,这一切都很好,但现在说你对这个计算器不满意,现在希望它有一些科学的计算功能。假设您现在想要为方形,平方根,指数和对数添加按钮,但不仅如此,您还希望在显示屏下方和数字和基本操作按钮上方添加按钮。如果您使用null布局执行此操作,则必须重新定位所添加的任何新组件的下方和右侧的所有组件,并且您必须扩展JTextField的大小,所有计算都是单调且易于进行的错误。
如果你使用了布局管理器,你只需要添加一行代码,实际上是一个数组的附加行:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.*;
public class CalcEg {
private static final float BTN_FONT_SIZE = 20f;
private static final String[][] BTN_LABELS = {
{"sqr", "sqrt", "exp", "log"}, // ******* Line Added Here *********
{"7", "8", "9", "-"},
{"4", "5", "6", "+"},
{"1", "2", "3", "/"},
{"0", ".", " ", "="}
};
private static final int GAP = 4;
private JPanel mainPanel = new JPanel(new BorderLayout(GAP, GAP));
private JPanel buttonPanel = new JPanel();
private JTextField display = new JTextField();
public CalcEg() {
int rows = BTN_LABELS.length;
int cols = BTN_LABELS[0].length;
buttonPanel.setLayout(new GridLayout(rows, cols, GAP, GAP));
for (String[] btnLabelRow : BTN_LABELS) {
for (String btnLabel : btnLabelRow) {
if (btnLabel.trim().isEmpty()) {
buttonPanel.add(new JLabel());
} else {
JButton btn = createButton(btnLabel);
buttonPanel.add(btn);
}
}
}
display.setFont(display.getFont().deriveFont(BTN_FONT_SIZE));
display.setEditable(false);
display.setFocusable(false);
display.setBackground(Color.white);
mainPanel.setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
mainPanel.add(buttonPanel, BorderLayout.CENTER);
mainPanel.add(display, BorderLayout.PAGE_START);
}
private JButton createButton(String btnLabel) {
JButton button = new JButton(btnLabel);
button.setFont(button.getFont().deriveFont(BTN_FONT_SIZE));
return button;
}
public JComponent getMainComponent() {
return mainPanel;
}
private static void createAndShowGui() {
CalcEg mainPanel = new CalcEg();
JFrame frame = new JFrame("CalcEg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel.getMainComponent());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
会导致此GUI:
同样,这是一个非常简单的示例,但一般原则适用于任何包含JButtons,JTextComponents等组件的GUI。
答案 1 :(得分:1)
使用Swing动画,Timer类是一个特殊选项。
//this class is a JPanel that implements ActionListener`
Timer t = new Timer(1000,this);//the first arg is how many times it repeats in milliseconds
//Then in the constructor...
t.start();
//the ActionPerformed function normally increments a variable then calls the repaint method.
rectangle_x++;
repaint(); //calls paintComponent
另一个好主意是将g转换为Graphics2D对象 - 它更安全,更强大。
答案 2 :(得分:1)
使用Timer类的另一种方法:
Timer t = new Timer(510, new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
rectangle_x++;
repaint();
}
})
...
t.start();
你仍然需要在主类中覆盖actionPerformed()。