this 、 this 、および this の投稿から興味深いアイデアと批評を得ました(問題のGUIのコードについては、最後の投稿を参照してください)。それにもかかわらず、私はまだいくつかのことについてかなり混乱しています。主に、ユーザーが導入したグラフィックを表示する最も安価な方法は何ですか?
より具体的には、paintComponent()
メソッドと一緒にMouseDragged()
メソッドでこのクラスのオブジェクトを作成することにより、JPanel
クラスのpaintComponent(getGraphics())
メソッドを使用しました( _AuxClass2
_および_AuxClass1
_に応じて)。
どうやら、getGraphics()
の代わりにpaintComponent()
とrepaint()
を使用するのは悪い考えです。メモリの使用と関係があるのではないかと思います。また、ユーザーがマウスをドラッグするたびに_AuxClass2
_を呼び出すこともお勧めできません。
また、JPanelとCanvas(つまり、swingとawt)は少し混乱しています。何がいつ使用されますか?
私は回避策を見つけようとしましたが、特にgetGraphics()
メソッドの場合は回避策を見つけていません。他にどのようにグラフィックスをパネルに追加できますか?
私は回避策を見つけようとしましたが、特にgetGraphics()メソッドの場合は回避策を見つけていません。グラフィックをパネルに追加するにはどうすればよいですか。
何を変数としてペイントする必要があるかを覚えて、それをpaintComponent()で使用します。たとえば、あなたが他の質問でやろうとしているように見えることは次のようになります:
import Java.awt.*;
import Java.awt.event.*;
import javax.swing.*;
public class PaintRectangle extends JPanel {
private Point mouseLocation;
public PaintRectangle() {
setPreferredSize(new Dimension(500, 500));
MouseAdapter listener = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
updateMouseRectangle(e);
}
private void updateMouseRectangle(MouseEvent e) {
mouseLocation = e.getPoint();
repaint();
}
@Override
public void mouseDragged(MouseEvent e) {
updateMouseRectangle(e);
}
@Override
public void mouseReleased(MouseEvent e) {
mouseLocation = null;
repaint();
}
};
addMouseListener(listener);
addMouseMotionListener(listener);
}
private Rectangle getRectangle() {
if(mouseLocation != null) {
return new Rectangle(mouseLocation.x - 5, mouseLocation.y - 5, 10, 10);
}
else {
return null;
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Rectangle rectangle = getRectangle();
if(rectangle != null) {
Graphics2D gg = (Graphics2D) g;
gg.setColor(Color.BLUE);
gg.fill(rectangle);
gg.setColor(Color.BLACK);
gg.draw(rectangle);
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(new PaintRectangle());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
基本的に、重いコンポーネントは独自のネイティブピアにリンクされ、軽量コンポーネントは共通のネイティブピアを共有します。
一般に、Zオーダーに問題があり、私の経験では(現在はより良いはずですが)塗装の問題が発生する可能性があるため、重量コンポーネントと軽量コンポーネントを混合することはお勧めできません。
これがCanvas
クラスの使用を思いとどまらせた理由です。おそらく、軽量コンポーネントに配置しようとしていたからでしょう...
Swing API の初心者にとっての最大の問題の1つは、描画プロセスを何らかの方法で制御できるという幻想ですが、そうではありません。受け入れるだけの方が簡単です。
あなたができる最善のことは、再描画マネージャができるだけ早く更新を実行するように要求することです。
また、getGraphics
を呼び出してもnull以外の値が返されるとは限りません。
Paint
対paintComponent
ここでの問題はPaint
がいくつかの重要な仕事をしていることです。paintComponent
の呼び出しはその1つにすぎません。
Swingでは、カスタムペイントを実行する場合は常にpaintComponent
を使用することを強くお勧めします。これは通常、コンポーネントの最下位レベルであり、子コンポーネントがペイントされる前に呼び出されます。
Paint
をオーバーライドし、Graphics
をsuper.Paint
の呼び出し後にペイントすると、すべての上にペイントされることになりますが、これは必ずしも望ましい結果とは限りません
たとえあったとしても、子コンポーネントは親コンテナとは独立してペイントできるため、追加したペイントエフェクトの上に「ペイント」できます。
役立つリンク
別れの考え
ネイティブピアに接続されているコンポーネントに実際に追加されたコンポーネントのみが、Paint
メソッドが呼び出されます。したがって、まだコンテナに追加されていないコンポーネントにペイントしようとしても、意味がありません...
..paintbrush-type GUI ..
BufferedImage
を描画面として使用します。 JLabel
に表示します。 JScrollPane
内のパネルの中央にラベルを配置します。
必要に応じてbufferedImage.getGraphics()
を呼び出しますが、完了したらdispose()
を忘れずにlabel.repaint()
を呼び出します。
全体でSwingコンポーネントを使用し、何もオーバーライドしないでください。
これが 画像をペイントサーフェスとして使用する例 です。
そして これはより良いものです !
screen-shotの方が優れていたとは言いませんでした。コードの方が優れています。 ;)