当我从Square实例创建Board实例时,我尝试将窗口的大小分配给整数x和y。我没有这样做,因为它似乎在开始时大小为0.在Board.java的构造函数中,x和y不应该像-50一样现在最终结束。
Square.java:
package Square;
import javax.swing.*;
public class Square extends JFrame {
public Square(){
add(new Board());
setSize(800, 800);
setVisible(true);
}
public static void main(String[] args){
new Square();
}
}
Board.java
package Square;
import javax.swing.*;
import java.awt.*;
public class Board extends JPanel{
int x,y;
public Board(){
x = width-50;
y = height-50;
}
public int width = (int) getSize().getWidth();
public int height = (int) getSize().getHeight();
public void paintComponent(Graphics g){
super.paintComponent(g);
g.fillRect(x,y, 100, 100);
}
}
完整守则澄清: Square.java
package Square;
import javax.swing.*;
public class Square extends JFrame {
public Square(){
Board board = new Board();
board.start();
add(board);
setTitle("Square");
setSize(800, 800);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args){
Square square = new Square();
square.setVisible(true);
square.setLocation(2000, 150);
}
}
Board.java
package Square;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Board extends JPanel implements ActionListener{
Timer timer;
int x, y;
int velX = 0;
int velY = 0;
public Board(){
setFocusable(true);
timer = new Timer(1, this);
addKeyListener(new TAdapter());
}
class TAdapter extends KeyAdapter{
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
switch(keyCode){
case KeyEvent.VK_ESCAPE: x = width()/2-50; y = height()/2-50; break;
case KeyEvent.VK_RIGHT: velX = 1; break;
case KeyEvent.VK_DOWN: velY = 1; break;
case KeyEvent.VK_LEFT: velX = -1; break;
case KeyEvent.VK_UP: velY = -1; break;
}
}
public void keyReleased(KeyEvent e){
velX = 0;
velY = 0;
}
}
public int width(){ return (int) getSize().getWidth();}
public int height(){ return (int) getSize().getHeight();}
public void start(){
timer.setInitialDelay(100);
timer.start();
x = width()/2-50;
y = height()/2-50;
}
@Override
public void actionPerformed(ActionEvent e) {
x += velX;
y += velY;
repaint();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.RED);
g.fillRect(x,y, 100, 100);
}
}
答案 0 :(得分:5)
将计算放入paintComponent方法中。通常,您希望避免在paintComponent中使用会降低速度的代码,但这些调用不应该给予太多惩罚。此外,如果您的程序重新调整大小,您需要能够像这样重新计算出事物的大小:
Page<Person> findByNameOrAge(String name, int age,Pageable pageable);
但当然在你的真实节目中,你会想要避免&#34;魔法&#34;编号
另一个问题:请勿在您的JFrame上调用public void paintComponent(Graphics g){
super.paintComponent(g);
int x = getWidth() - 50;
int y = getHeight() - 50;
g.fillRect(x, y, 100, 100);
}
。相反,如果要指定硬件大小,请通过覆盖其setSize()
方法在JPanel中执行此操作。这也将为您提供可用于计算的建议参数。
例如:
getPreferredSize()
另外,请查看我的this answer中的键绑定动画代码。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
@SuppressWarnings("serial")
public class DrawRect extends JPanel {
private static final int PREF_W = 800;
private static final int PREF_H = PREF_W;
private static final int DELTA = 50;
private static final Color RECT_COLOR = Color.red;
private static final int RECT_WIDTH = 100;
private static final int TIMER_DELAY = 15;
private int rectX = PREF_W - DELTA;
private int rectY = PREF_H - DELTA;
public DrawRect() {
new Timer(TIMER_DELAY, new TimerListener()).start();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(RECT_COLOR);
g.fillRect(rectX, rectY, RECT_WIDTH, RECT_WIDTH);
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class TimerListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
rectX--;
rectY--;
repaint();
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("DrawRect");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new DrawRect());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
答案 1 :(得分:2)
嘿,你的代码风格很糟糕,但我试着帮助:)。您无法获得未拉伸窗口的大小。首先,您的构造函数是错误的,您添加实际创建Board Obj的Board。调用Board的构造函数,它没有绘制父级,也没有设置x,y。尝试在构造函数中初始化变量。所以只需使用宽度和高度并填充构造函数中的值。接下来,通过将其父级大小传递给构造函数变量,告诉您的电路板其创建大小。 我想你试着学习java,这更优雅。此外,尝试在向其添加一些之前进行所有父修改。首先是setSize,添加一些Layout(Border / Flow / whatuwish),然后获取FramePane帧并添加你的Board组件。为了清楚起见,你不能得到例如Contructor中的父级和父级大小,因为您的主板Obj尚未创建和添加。如果你想要getParent()及其大小,创建Object将它添加到JFrame,然后你可以调用getParent()。getSize()。你得到0因为你的JPanel目前没有被绘制(在创建之前)。如果您希望获得父级大小,只需将JFrame参考传递给构造函数或其大小。另一个建议,不要在事物中创造事物,请记住你创建JPanel的代码作为第一个Obj ...以下是一些示例代码: 正方形:
public class Square extends JFrame {
public static void main(String[] args){
Square square = new Square();
square.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Dimension d = new Dimension(800,800);
square.setPreferredSize(d);
square.setSize(d);
//too much, every Jframe has BorderLayout enabled
square.getContentPane().setLayout(new BorderLayout());
square.getContentPane().add(new Board(square), BorderLayout.CENTER);
square.pack();
square.setVisible(true);
}
}
板:
public class Board extends JPanel{
int x,y;
JFrame parent;
public Board(JFrame parent){
int width = parent.getPreferredSize().width;
int height = parent.getPreferredSize().height;
x = width-50;
y = height-50;
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g.fillRect(x,y, 100, 100);
}
}
答案 2 :(得分:1)
例如,在下一个EDT周期中,您可以通过使用SwingUtilities.invokeLater在面板变得可见后获取x和y值。