[英]Java Jpanel paint
我有一個Java jpanel的示例:
import java.awt.*;
import javax.swing.*;
public class JavaGame extends JFrame {
public JavaGame() {
setTitle("Game");
setSize(500,500);
setResizable(false);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void paint(Graphics g) {
g.drawString("Hello World!",75,75);
}
public static void main(String[] args) {
new JavaGame();
}
}
因此,我們僅定義方法paint
,然后創建新的JavaGame對象,並且僅調用paint
。 我沒有兩件事:
- new JavaGame()-我們是否應該分配一個對象名稱,例如obj = new JavaGame()?
- 我們不應該像obj.paint()那樣調用paint方法嗎?
我對OOP有基本的了解,但是這段代碼使我感到困惑。 有人可以給我解釋一下嗎?
new JavaGame()-我們是否應該分配一個對象名稱,例如obj = new JavaGame()?
這達到了對象和參考變量之間的重要區別。 這里最重要的是創建一個JavaGame對象,您可以通過new JavaGame()
。 由於此對象在其構造函數中顯示JFrame,因此只需創建對象即可創建顯示,而無需將對象分配給任何變量。
請注意, 對象沒有名稱,但是有些變量具有名稱。 例如,如果您創建了一個Foo對象,並將其分配給bar變量:
Foo bar = new Foo();
但是然后將相同的對象分配給baz變量:
Foo baz = bar;
bar和baz均指完全相同的Foo對象。 那么對象的名稱是什么? 同樣,對象名稱不存在並且沒有意義。
我們不應該像obj.paint()那樣調用paint方法嗎?
正如MightyPork(對他而言為1+)所指出的那樣,paint方法是由JVM調用的 ,不應由您直接調用。 您可以建議通過調用repaint()
調用它,但幾乎永遠不要直接調用它,也不要直接調用paintComponent(...)
方法。
其他事宜:
編輯你問:
因此,當使用API時,我們只需在代碼中“填充”類中的方法,JVM就會知道何時調用這些方法?
大多數情況下,Swing圖形是“被動的”。 意味着您將組件設置為以某種方式繪制,但您自己不會主動進行繪制。 而是由JVM(Java虛擬機-運行Java程序的代碼)為您繪制圖形。 如果要制作動畫,通常會更改一些位置變量,例如xPosition和yPosition int變量,然后在JPanel的paintComponent(Graphics g)
方法中使用這些變量。 因此,如果您在Swing計時器中更改了這些變量所保存的值,然后在值更改后調用repaint()
,JVM將(通常)使用新值來重新繪制您的組件。
一個更復雜的示例,它在JPanel中顯示繪圖,並顯示一個非常簡單的動畫:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
// draw in a JPanel, not a JFrame
public class SimpleAnimation extends JPanel {
private static final int OVAL_WIDTH = 40;
private static final int TIMER_DELAY = 50;
private static final int PREF_W = 800;
private static final int PREF_H = PREF_W;
private int xPosition = 0;
private int yPosition = 0;
public SimpleAnimation() {
// start my timer here
new Timer(TIMER_DELAY, new TimerListener()).start();
}
@Override
protected void paintComponent(Graphics g) {
// call the super method so that the JPanel
// can do its own house-keeping graphics first
super.paintComponent(g);
// I do this to so that my graphics are smooth
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.red);
// use xPosition and yPosition to place my oval
g2.fillOval(xPosition, yPosition, OVAL_WIDTH, OVAL_WIDTH);
}
// so our GUI will be big enough to see
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
// class used by the Swing Timer to drive animation
private class TimerListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
// change xPosition and yPosition
xPosition++;
yPosition++;
// and call repaint
repaint();
}
}
// a method to be called in our Runnable
private static void createAndShowGui() {
SimpleAnimation mainPanel = new SimpleAnimation();
JFrame frame = new JFrame("SimpleAnimation");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
// this is used to make sure that all Swing code
// is started on the Swing event thread.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
您創建對象new JavaGame()
而不將其分配給任何變量,僅此而已。
Swing渲染和事件線程開始運行,並照顧了應用程序的剩余生命。
我不確定垃圾收集器為什么不撿起並結束它,但是我已經用這種方式做了很長時間了,並且效果很好。
new
,將調用構造函數,從而創建框架。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.