ハローみんな。フレームAのコンポーネント内に、外部コンポーネント(つまり、別のフレームのコンテンツペインに属する)をペイントしたいので、それをフレームBと呼びます。
問題は、コンポーネントをペイントすると、フレームAのコンテンツペインにもペイントされることです。また、フレームのサイズを変更すると、ちらつくか、すべてが醜くなります(つまり、コンポーネント内で数回ペイントすると、青い四角がいくつか表示されます。など)。たとえば、ペイントする前に異物を拡大縮小または変換しようとすると、問題がより明確になります。
しばらくして仕分けしたと思います。しかし、私はこの解決策に満足していません。何らかの理由で、より良い解決策、より適切な解決策があるかもしれないと信じています。ここにあなたが必要です。:)
この質問は、コンポーネント内のペイントの前後にダブルバッファリング機能を操作せずに、外部コンポーネントが正しくペイントされない理由を説明するための呼び出しです。たとえば、setDoubleBuffered(false)とsetDoubleBuffered(true)のペア、またはdisableDoubleBuffering(jP)とenableDoubleBuffering(jP)のいずれかを使用します。
それぞれ、外部コンポーネントのペイントメソッドの呼び出しの前後。
前もって感謝します。問題を示すSSCCEを以下に示します。
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.RepaintManager;
public class PaintForeignComponentSSCCE extends JFrame
{
public static void main(String[] args) throws IOException
{
//foreign panel
JPanel fp = new JPanel();
fp.setBackground(Color.PINK);
fp.setPreferredSize(new Dimension(200, 300));
//component in which the foreign panel is painted
ForeignComponentPainter fcp = new ForeignComponentPainter(fp);
fcp.setPreferredSize(new Dimension(600, 600));
//main frame's content
JPanel contentPane = new JPanel();
contentPane.setBackground(Color.BLUE);
contentPane.add(fcp);
//main frame
JFrame f = new PaintForeignComponentSSCCE();
f.setContentPane(contentPane);
f.setSize(700, 500);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
//foreign panel frame
JFrame fpf = new JFrame();
JPanel panelFrameContent = new JPanel();
panelFrameContent.add(fp);
fpf.setContentPane(panelFrameContent);
fpf.setSize(400, 400);
fpf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
fpf.setVisible(true);
}
}
class ForeignComponentPainter extends JButton
{
private static final long serialVersionUID = 1L;
private JPanel jP;
public ForeignComponentPainter(JPanel jP)
{
super();
this.jP = jP;
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.drawString("OIOI", 50, 50);
//g2.translate(100, 50);
//g2.scale(.5, .5);
// jP.setDoubleBuffered(false);
// disableDoubleBuffering(jP);
jP.paint(g2);
// jP.setDoubleBuffered(true);
// enableDoubleBuffering(jP);
//g2.scale(1/.5, 1/.5);
}
public static void disableDoubleBuffering(Component c)
{
RepaintManager currentManager = RepaintManager.currentManager(c);
currentManager.setDoubleBufferingEnabled(false);
}
public static void enableDoubleBuffering(Component c)
{
RepaintManager currentManager = RepaintManager.currentManager(c);
currentManager.setDoubleBufferingEnabled(true);
}
}
SSCCEの例とは関係ありません。 以下は問題自体とは関係ありません。 このコードは、印刷プレビュー形式でレンダリングしたいコンポーネントにPrintableを実装する方法を示す目的で使用されます。印刷では、コンポーネントのペイントが呼び出されます(以下を参照)。
public int print(Graphics g, PageFormat pageFormat, int pageIndex)
{
if(pageIndex >= pageHeights.size())
return NO_SUCH_PAGE;
int savedPage = currentPageIndex;
currentPageIndex = pageIndex;
Graphics2D g2 = (Graphics2D) g;
paint(g2);
currentPageIndex = savedPage;
return PAGE_EXISTS;
}