に埋め込んだ大きな「キャンバスのような」CAD コンポーネントにナビゲーション ウィンドウを提供するために、ここJScrollNavigatorで説明するコンポーネントを使用しています。JScrollPane
JScrollNavigatorユーザーに追加のコンテキストを提供するために、キャンバスのサムネイル画像を描画するように を適応させようとしました。ただし、これを実行すると、アプリケーションのメイン フレームのレンダリングが破損します。具体的にはpaint(Graphics)、ビューポート コンポーネント (つまり、私のメイン キャンバス)を呼び出し、Graphicsによって作成されたオブジェクトを渡すアクションがBufferedImage、その後の表示の破損を引き起こします。この行をコメントアウトすると、すべて正常に動作します。
以下は、JScrollNavigatorオーバーライドされたpaintComponentメソッドです。
@Override
protected void paintComponent(Graphics g) {
Component view = jScrollPane.getViewport().getView();
BufferedImage img = new BufferedImage(view.getWidth(), view.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
// Paint JScrollPane view to off-screen image and then scale.
// It is this action that causes the display corruption!
view.paint(g2d);
g2d.drawImage(img, 0, 0, null);
Image scaled = img.getScaledInstance(getWidth(), getHeight(), 0);
super.paintComponent(g);
g.drawImage(scaled, 0, 0, null);
}
破損の原因について何か提案はありますか? オフスクリーン イメージへのペイントは、既存のペイント操作に影響を与えるべきではないと考えていたでしょう。
編集
追加の詳細を提供するには:JScrollNavigatorは、 の左側にサブパネルを形成しJSplitPaneます。ナビゲーターにJScrollPane関連付けられている は右側にあります。「破損」により、スプリッターがレンダリングされなくなり、スクロールバーが表示されなくなります (白く表示されます)。のサイズを変更するJFrameと、JMenuセクションも白くなります。ナビゲーターを使用したり、スクロールバーを操作しようとすると、それらは表示されますが、スプリッターは白のままです。さまざまなコンポーネントの不透明な設定が、ビューポート ビューをオフスクリーン イメージにレンダリングすることによって影響を受けているかのようです。
また、 をJScrollNavigator完全に別の に表示させるとJDialog、すべてが正しく機能します。
編集2
以下を実行することで、一貫して問題を再現できます。
JMenuBarに aを追加mFrame:
JMenuBar bar = new JMenuBar();
bar.add(new JMenu("File"));
mFrame.setJMenuBar(bar);
置換のmain()方法では:JScrollNavigator
jsp.setViewportView(textArea);
... と:
jsp.setViewportView(new JPanel() {
{
setBackground(Color.GREEN);
setBorder(BorderFactory.createLineBorder(Color.BLACK, 5));
}
});
が別個の として表示されるのではなく、JScrollNavigator内にパネルとして埋め込まれていることを確認します。mFrameJDialog
mFrame.add(jsp, BorderLayout.CENTER);
mFrame.add(nav, BorderLayout.NORTH);
アプリケーションを実行すると、JMenuBar は表示されなくなります。によって返されるにビュー (つまり、JPanel太い黒の境界線を持つ緑) をペイントする行為は、実際には、おそらく JFrame の左上隅から、画面上にレンダリングしているように見えます。そのため、他のコンポーネントが見えなくなります。これは、 がビューポート ビューとして使用され、、 などの別のコンポーネントが使用されていない場合にのみ発生するようです。Graphics2DBufferedImage.createGraphics()JPanelJTextAreaJTable
編集3
この人が同じ問題を抱えていたようです (解決策は投稿されていません): http://www.javaworld.com/community/node/2894/
編集4
編集 2 で説明されている再現可能なエラーが発生するメソッドmainとメソッドは次のとおりです。paintComponent
public static void main(String[] args) {
JScrollPane jsp = new JScrollPane();
jsp.setViewportView(new JPanel() {
{
setBackground(Color.GREEN);
setBorder(BorderFactory.createLineBorder(Color.BLACK, 5));
}
});
JScrollNavigator nav = new JScrollNavigator();
nav.setJScrollPane(jsp);
JFrame mFrame = new JFrame();
JMenuBar bar = new JMenuBar();
bar.add(new JMenu("File"));
mFrame.setJMenuBar(bar);
mFrame.setTitle("JScrollNavigator Test");
mFrame.setSize(800, 600);
mFrame.setLayout(new GridLayout(1, 2));
mFrame.add(jsp);
mFrame.add(nav);
Dimension screenDim = Toolkit.getDefaultToolkit().getScreenSize();
mFrame.setLocation((screenDim.width - mFrame.getSize().width) / 2, (screenDim.height - mFrame.getSize().height) / 2);
mFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mFrame.setVisible(true);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Component view = jScrollPane.getViewport().getView();
if (img == null) {
GraphicsConfiguration gfConf = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
img = new BufferedImage(view.getWidth(), view.getHeight(), BufferedImage.TYPE_INT_ARGB);
}
Graphics2D g2d = img.createGraphics();
view.paint(g2d);
Image scaled = img.getScaledInstance(getWidth(), getHeight(), 0);
g.drawImage(scaled, 0, 0, null);
}
編集5
他の人が正確な問題を再現するのに苦労しているようです。ここに貼り付けたコードを実行してもらいたいと思います。この例を最初に実行すると、次のように表示されます。

JScrollNavigator も JMenuBar も描画されていません。これらのフレーム領域は透明です。
サイズ変更後、次のように表示されます。

はJMenuBarまだペイントされておらずJPanel、ある時点で (0,0) (あるJMenuBarべき場所) でレンダリングされたようです。内部のview.paint呼び出しpaintComponentは、これの直接の原因です。



