【问题标题】:Using JSplitPane with an AWT component将 JSplitPane 与 AWT 组件一起使用
【发布时间】:2011-04-29 07:18:57
【问题描述】:

我有一个无法转换为 Swing 组件的 AWT 画布(它来自 VTK)。我希望在 JSplitPane 中显示其中一些画布。我已经阅读了有关在 Java 中混合重型和轻型组件的文章,并且知道这很麻烦,但我别无选择。如果我将 AWT 画布包装在 JPanel 内,然后将其放在拆分窗格上,则拆分窗格根本不起作用。但是,如果我将 AWT 画布放在 JPanel 内,然后将其放在 JScrollPane 内,然后在 JSplitPane 上的那些滚动窗格,拆分窗格确实起作用,但 AWT 画布组件无法正确调整大小。当 JSplitPane 的分隔线被移动时,我不知道如何让 AWT 画布组件正确调整大小。当时我可以捕捉分隔线移动操作并在AWT画布上进行操作,但我不知道该怎么做。我试过调用 invalidate() 然后 validate() 然后 repaint(),但是没有用。

有什么想法吗?

这是一个问题的例子

import javax.swing.*;
import java.awt.*;

public class SwingAWTError {
    public static void main(String[] args) {
        Canvas leftCanvas = new Canvas();
        Canvas rightCanvas = new Canvas();
        leftCanvas.setBackground(Color.RED);
        rightCanvas.setBackground(Color.BLUE);

        JPanel leftPanel = new JPanel();
        JPanel rightPanel = new JPanel();
        leftPanel.setLayout(new BorderLayout());
        rightPanel.setLayout(new BorderLayout());
        leftPanel.add(leftCanvas, BorderLayout.CENTER);
        rightPanel.add(rightCanvas, BorderLayout.CENTER);

        JScrollPane leftScroll = new JScrollPane();
        JScrollPane rightScroll = new JScrollPane();
        leftScroll.getViewport().add(leftPanel);
        rightScroll.getViewport().add(rightPanel);

        JSplitPane split = new JSplitPane();
        split.setLeftComponent(leftScroll);
        split.setRightComponent(rightScroll);
        split.setDividerLocation(400);

        JFrame frame = new JFrame();
        frame.getContentPane().setLayout(new BorderLayout());
        frame.getContentPane().add(split, BorderLayout.CENTER);
        frame.setSize(800, 800);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

【问题讨论】:

  • 您的意思是 JScrollPane 而不是 JScrollBar?
  • 也许 SSCCE (sscce.org) 会帮助我们发现问题。您可以创建自己的简单 Canvas,而无需使用 VTK 来演示问题。您还可以升级到现在支持混合 AWT 组件的 JDK 1.6.17 (?) 或 JDK 1.7。
  • 我添加了一个简短的类来显示问题的示例。
  • 我也在用JDK1.6 17编译

标签: java swing awt jsplitpane


【解决方案1】:

这是一种肮脏的方式,但这会解决它:

当您在不调整窗口大小的情况下调用 pack() 时,不会发生太多事情。因此,当您第一次调整窗口大小然后调用pack() 时,您的组件将被正确绘制。这意味着您可以将此脏方法放入您的分隔符移动侦听器方法中:

frame.setPreferredSize(frame.getSize()); // store the current size to restore it after packing.
frame.setSize(frame.getWidth() + 1, frame.getHeight()); // resize it!!
frame.pack();

我不知道它到底是什么,但它在 Java 中是一种奇怪的行为...
希望这对您有所帮助,直到您找到更好的解决方案...

【讨论】:

    【解决方案2】:

    你在这里有点不走运。在 sun/oracle 网站上有一篇很好的文章: http://java.sun.com/products/jfc/tsc/articles/mixing/

    基本上它归结为这个指南(取自该链接,在 z 排序标题下):

    不要将轻量级(Swing)和 重量级 (AWT) 组件 轻量级的容器 预计组件将重叠 重量级的。

    编辑:我一直在浏览该网站并遇到另一个链接,情况似乎略有改善:http://java.sun.com/developer/technicalArticles/GUI/mixing_components/ 但我认为您的情况是限制部分底部列出的情况之一:

    限制

    有几种情况不支持:

    * Non-opaque lightweight components that have translucent
    

    像素 (0

    * Embedded heavyweight components must belong to the process that
    

    创建了框架或小程序。这 重量级组件必须有一个 主进程内的有效对等体 应用程序(或小程序)。

    * Advanced Swing key events, such as those events maintained in an
    

    InputMap,可能无法正常工作 轻量级和重量级 组件正在混合。有 没有已知的解决方法。

    【讨论】:

    • 显然这不是我想听到的。您列出的三种情况中,我属于哪一种?另外,是否有任何关于在未来 Java 版本中解决这些问题的讨论?
    • 对不起,我只是猜测。多年来我一直不用使用 Swing,这就是为什么我什至不知道他们对某些情况进行了修复。
    猜你喜欢
    • 1970-01-01
    • 2011-04-23
    • 2012-06-22
    • 2014-02-12
    • 1970-01-01
    • 2021-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多