Using JSplitPane with AWT Component

I have an AWT canvas that I cannot convert to a Swing component (it comes from VTK ). I want to display some of these paintings inside JSplitPane. I read about mixing heavy and light components in Java and I know that this is a pain in the butt, but I have no choice. If I wrap the AWT canvas inside a JPanel and then put it on the split panel, the split panel doesn't work at all. However, if I placed the AWT canvas inside the JPanel, and then inside the JScrollPane, and then these scrollbars on the JSplitPane, the split panel works, but the components of the AWT canvas do not change correctly. I'm lost on how to get AWT canvas components to resize correctly when the JSplitPane separator moves. I can catch the divider move operation and work on AWT canvases at that time, but I don't know what to do. I tried calling invalidate (), then validate (), and then repaint (), but that didn't work.

Any ideas?

Here is an example of a problem

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); } } 
+4
source share
2 answers

This is a dirty way, but it will solve it:

When you call pack() without resizing the window, this does not happen. So, when you first resize the window and then call pack() , your components will be drawn correctly. This means that you can put this dirty method in your listener method, moved by the delimiter:

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

I don't know what this is for sure, but this is a weird behavior in Java ...
Hope this helps until you find a better solution ...

+4
source

You are out of luck here. There's a very good article on this on the sun / oracle website: http://java.sun.com/products/jfc/tsc/articles/mixing/

Essentially it comes down to this guide (taken from this link under the z heading):

Do not mix light weight (Swing) and super heavy (AWT) components within a container where a light component is expected to overlap a heavy one.

Edit: I continued to browse this site and came across another link, and it would seem that the situation improved a bit: http://java.sun.com/developer/technicalArticles/GUI/mixing_components/ But I think your case is one of the following at the bottom of the restrictions section:

Limitations

Several situations are not supported:

 * Non-opaque lightweight components that have translucent 

pixels (0 <alpha <255) are not supported. If a partially translucent lightweight component overlaps the heavyweight, the heavyweight component will not be displayed.

 * Embedded heavyweight components must belong to the process that 

created a frame or applet. the heavyweight component must have a valid peer in the main application process (or applet).

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

InputMap may not work properly where light and heavy components mix. There are no known workarounds.

+2
source

All Articles