Community
Participate
Working Groups
This code snippet shows how a JSplitPane does not have the resizable arrows whereas a SashForm does. This is on Suse 9.0, JDK 1.5 beta, and the 3044 nightly build of SWT for GTK. ------------------------- import org.eclipse.swt.*; import org.eclipse.swt.events.*; import org.eclipse.swt.widgets.*; import org.eclipse.swt.layout.*; import org.eclipse.swt.graphics.*; import org.eclipse.swt.custom.*; import javax.swing.JFrame; import javax.swing.JList; import javax.swing.JScrollPane; import java.awt.GridBagLayout; import java.awt.GridBagConstraints; import java.util.*; import java.awt.Frame; import java.awt.Dimension; import org.eclipse.swt.awt.SWT_AWT; /** * Description of the Class * * @author david * @created April 13, 2004 */ public class SupraSphereFrame { Display display; Shell shell; TabFolder tabFolder; GridData gridData0; Hashtable tabs = new Hashtable(); boolean isLayoutDone = false; GridLayout gl = new GridLayout(); /** *Constructor for the SupraSphereFrame object */ public SupraSphereFrame() { } /** * The main program for the SupraSphereFrame class * * @param args The command line arguments */ public static void main(String[] args) { SupraSphereFrame sf = new SupraSphereFrame(); sf.layoutSupraFrame(); } /** * Adds a feature to the Tab attribute of the SupraSphereFrame object * * @param name The feature to be added to the Tab attribute * @param mP The feature to be added to the Tab attribute */ public void addTab(final String name, final MessagesPane mP) { Thread t = new Thread() { public void run() { System.out.println("starting add tab"); TabItem mpItem = new TabItem(tabFolder, SWT.NULL); mpItem.setText(name); tabs.put(name, mpItem); gridData0.verticalAlignment = GridData.FILL; gridData0.horizontalAlignment = GridData.FILL; gridData0.grabExcessHorizontalSpace = true; gridData0.grabExcessVerticalSpace = true; Composite mpComp = new Composite(tabFolder, SWT.EMBEDDED); java.awt.Frame mpFrame = SWT_AWT.new_Frame(mpComp); mpFrame.add(mP); mpItem.setControl(mpComp); shell.layout(); System.out.println("added tab"); } }; display.asyncExec(t); } /** * Adds a feature to the Tab attribute of the SupraSphereFrame object * * @param name The feature to be added to the Tab attribute * @param image The feature to be added to the Tab attribute * @param mP The feature to be added to the Tab attribute */ public void addTab(final String name, final java.awt.Image image, final MessagesPane mP) { Thread t = new Thread() { public void run() { System.out.println("starting add tab"); TabItem mpItem = new TabItem(tabFolder, SWT.NULL); mpItem.setText(name); //mpItem.setImage(image); tabs.put(name, mpItem); gridData0.verticalAlignment = GridData.FILL; gridData0.horizontalAlignment = GridData.FILL; gridData0.grabExcessHorizontalSpace = true; gridData0.grabExcessVerticalSpace = true; Composite mpComp = new Composite(tabFolder, SWT.EMBEDDED); java.awt.Frame mpFrame = SWT_AWT.new_Frame(mpComp); mpFrame.add(mP); mpItem.setControl(mpComp); shell.layout(); System.out.println("added tab"); } }; display.asyncExec(t); } /** * Description of the Method * * @param title Description of the Parameter */ public void removeTab(final String title) { Thread t = new Thread() { public void run() { TabItem removeItem = (TabItem) tabs.get(title); removeItem.dispose(); } }; display.asyncExec(t); } /** * Description of the Method */ public void layoutSupraFrame() { display = new Display(); shell = new Shell(display); shell.setSize(800, 600); gl.numColumns = 2; shell.setLayout(gl); tabFolder = new TabFolder(shell, SWT.NONE); gridData0 = new GridData(); tabFolder.setLayoutData(gridData0); final TabItem ti = new TabItem(tabFolder, SWT.NONE); ti.setText("One"); shell.setLayout(new FillLayout()); final SashForm form = new SashForm(tabFolder, SWT.HORIZONTAL); form.setBackground(new Color(display, new RGB(200, 200, 200))); form.setLayout(new FillLayout()); form.SASH_WIDTH = 4; final Composite child = new Composite(form, SWT.NONE); child.setLayout(new FillLayout()); String[] values = {"One", "Two", "Three"}; javax.swing.JList topList = new javax.swing.JList(values); javax.swing.JScrollPane topScroll = new javax.swing.JScrollPane(topList); javax.swing.JList botList = new javax.swing.JList(values); javax.swing.JScrollPane botScroll = new javax.swing.JScrollPane(botList); final javax.swing.JSplitPane sp = new javax.swing.JSplitPane(javax.swing.JSplitPane.HORIZONTAL_SPLIT, topScroll, botScroll); Thread t = new Thread() { public void run() { Composite mpComp = new Composite(child, SWT.EMBEDDED); java.awt.Frame mpFrame = SWT_AWT.new_Frame(mpComp); mpFrame.add(sp); mpFrame.setBackground(java.awt.Color.white); ti.setControl(form); shell.layout(); } }; display.asyncExec(t); TabItem t2 = new TabItem(tabFolder, SWT.NONE); t2.setText("Two"); Composite child3 = new Composite(form, SWT.NONE); child3.setLayout(new FillLayout()); new Label(child3, SWT.NONE).setText("Label in pane3"); show(); } /** * Description of the Method */ public void show() { // Final setup - size the display show it // shell.setSize(200, 100); // ***SN - don't set the intital size shell.layout(); shell.open(); System.out.println("Done show"); isLayoutDone = true; while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } }
Created attachment 9437 [details] Same code as pasted...
Interop issue? SSQ to look.
Note that if you move the window to the top/left corner of the screen, so that the border of the window is actually out of screen the cursor changes to be the resize cursor.
You can workaround this problem by adding a java.awt.Panel in between the embedded frame and the lightweight components.
Here is simple testcase that shows the problem (the button will not have a CROSS cursor unless the window is in the top/left corner of the screen): public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setLayout(new FillLayout()); Composite comp = new Composite(shell, SWT.EMBEDDED); Frame frame = SWT_AWT.new_Frame(comp); //JSplitPane split = new JSplitPane(); //frame.add(split); JButton button = new JButton(); frame.add(button); button.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); shell.setBounds(300, 300, 100, 100); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } }
Changed the platform field, since the problem happens on Windows and Motif too.
Fixed > 20040422.
The fix for this problem causes layout problems (see bug#64365). We are removing it.
Will it be fixed at some point again? Is there a long term solution?
This is a problem with the AWT embedded frame and SWT cannot work around it. We have updated the java doc of SWT_AWT.new_Frame() to warn about this issue and suggest the app code to add a child heightweight component as a work around. Unless AWT fixes the problem, this workaround will be the long term solution. public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setLayout(new FillLayout()); Composite comp = new Composite(shell, SWT.EMBEDDED); Frame frame = SWT_AWT.new_Frame(comp); // WORKAROUND Panel panel = new Panel(new BorderLayout()); frame.add(panel); JButton button = new JButton(); panel.add(button); button.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); shell.setBounds(300, 300, 100, 100); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } }
Hello, I just tried to implement the workaround and I get: test.java:32: cannot resolve symbol symbol : variable CROSSHAIR_CURSOR location: class org.eclipse.swt.graphics.Cursor button.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); ^ 1 error This is with SWT 3.0 release, Windows XP, java 1.4.2_04. David
First, the following segment of the code is not part of the workaround. It is just showing that cursors can be set in a swing button if you add it to a java.awt.Panel. ... JButton button = new JButton(); panel.add(button); button.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); ... Second, you are importing the wrong Cursor class. You should import "java.awt.Cursor" instead of org.eclipse.swt.graphics.Cursor.
I'm very sorry to continue this thread, but I still can't find an acceptable work-around for this. This is now more critical because I have to move to swt 3.0 for another bug whereas I have been using the last version that didn't include the retraction of code that fixed this problem. If I understand correctly, you are suggesting to change the cursor icon? How do I change the cursor to be different only for the JSPlitPane divider and not the rest of it? Even if the cursor changes, it still doesn't behave the same way as with a regular JSplitPane. The actual pixels that may be used to resize the split pane are different, such that you not only have to line up the pointer with an area different/inconsistent with a JSplitPane, but it also happens to be a much smaller area. This makes it extremely frustrating to use, unless I make the divider size huge, which just looks awful. Even so, the cursor will have to change *only* when it becomes possible to resize it, not just when it moves over the divider. Can you suggest any alternative to this? This has put me in a really awful position because I have a critical issue that was fixed with 3.0 but this problem is preventing me from using it. Thank you for your continued help.
Created attachment 13724 [details] code with workaround Ok, I am NOT suggesting to change the cursor icon. I guess I was not clear. Here is a version of the code in comment#1 modified to make it work. Search for the comment "//------------ Lines SSQ added/changed".
Worked wonderfully! Thank you so much!
*** Bug 82372 has been marked as a duplicate of this bug. ***
*** Bug 96708 has been marked as a duplicate of this bug. ***
*** Bug 130488 has been marked as a duplicate of this bug. ***
Thanks for the workaround.