Long menu item in Java AWT application not visible - java

When I start Java application with AWT GUI on remote server that uses my local X-server (Ubuntu 16.04 with Unity), menu items with long names are not visible. It is very interesting that I can see this behavior only on one specific server whilst it works on others.
Demonstration code is:
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class Main extends Frame {
public Main() {
this.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
Menu mn = new Menu("File");
MenuItem mi = new MenuItem("It is very very long text");
mn.add(mi);
mi = new MenuItem("long");
mn.add(mi);
MenuBar mb = new MenuBar();
mb.add(mn);
this.setLayout(new BorderLayout());
this.setMenuBar(mb);
this.setSize(200,200);
this.setVisible(true);
}
public static void main(String[] args) {
new Main();
}
}

Related

Bypass forced JOptionPane

I am using a scripting API for making a script for a bot for a game I play, however whenever I override a bot manager, a JOptionPane appears that blocks execution until I close it, however I would like to run this script without human intervention, so I would like to bypass this pane.
I have tried to overwrite the JOptionPane class at runtime to no avail, and I have tried contacting the developer of the bot's API to add an override however he doesn't want to add an override.
I am open to any methods of resolving this (reflection, etc.), I was thinking of detecting the pane's title and force-closing it however that it way beyond my skill level.
Pane title: Override Warning!
I would add the pane text however it reveals personal information.
Here is the possibility to suppress all JOptionPane dialogs. If you want to do it with some of them you probably need to provide additional check for dialog title.
import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class CloseDialog implements Runnable {
private final AWTEventListener hideOptionPaneListener = new AWTEventListener() {
#Override
public void eventDispatched(AWTEvent event) {
if (event instanceof WindowEvent) {
processWindowEvent((WindowEvent) event);
}
}
};
private void processWindowEvent(WindowEvent we) {
if (we.getID() == WindowEvent.WINDOW_OPENED && we.getWindow() instanceof JDialog) {
final JDialog dlg = (JDialog) we.getWindow();
Component[] comps = dlg.getContentPane().getComponents();
if (comps.length > 0 && comps[0] instanceof JOptionPane) { // probably also check dialog title
dlg.setVisible(false);
}
}
}
#Override
public void run() {
final JFrame frm = new JFrame("Test frame");
JButton button = new JButton("Show option pane");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(frm, "Simple message");
}
});
final JCheckBox checkBox = new JCheckBox("Suppress option pane");
checkBox.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (checkBox.isSelected()) {
Toolkit.getDefaultToolkit().addAWTEventListener(hideOptionPaneListener, AWTEvent.WINDOW_EVENT_MASK);
} else {
Toolkit.getDefaultToolkit().removeAWTEventListener(hideOptionPaneListener);
}
}
});
JPanel top = new JPanel(new FlowLayout());
top.add(button);
frm.add(top, BorderLayout.NORTH);
frm.add(checkBox, BorderLayout.SOUTH);
frm.setSize(400, 200);
frm.setLocationRelativeTo(null);
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new CloseDialog());
}
}

Making JavaFX FileChooser not show on the taskbar when used in Swing

I have looked at this page on how to use the JavaFX FileChooser with Swing, and it works well:
JavaFX FileChooser in swing
I have also looked at this page on how to make a stage now show in the taskbar with StageStyle.UTILITY:
JavaFX: can you create a stage that doesn't show on the task bar and is undecorated?
However, when I combine the two, the file dialog that I use in the swing application opens a separate window in the taskbar, that does not appear with JFileChooser. I was wondering how to make the JavaFX FileChooser not show in the taskbar when using it in a swing application.
Here is a snippet of code that demonstrates the issue:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.JButton;
import javax.swing.JFrame;
import javafx.application.Platform;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class Test extends JFrame implements ActionListener {
private JButton button;
private FileChooser chooser;
public Test(){
super();
setDefaultCloseOperation(EXIT_ON_CLOSE);
button = new JButton("Test");
button.addActionListener(this);
add(button);
new javafx.embed.swing.JFXPanel();
Platform.setImplicitExit(false);
chooser = new FileChooser();
pack();
setLocationRelativeTo(null);
setVisible(true);
}
public void actionPerformed(ActionEvent e){
Platform.runLater(new Runnable(){
public void run(){
Stage stage = new Stage();
stage.initStyle(StageStyle.UTILITY);
File testfile = chooser.showOpenDialog(stage);
}
});
}
public static void main(String[] args){
new Test();
}
}

Resize JDialog by pushing it against the edge of the screen

I have a JFrame and a JDialog. The latter simply contains a JTextArea. Windows 7 gives now the possibility to resize a window to the half of the screen by pushing it against the right or the left edge. This works fine with the JFrame window. However, the JDialog window does not react to it, though it is manually resizable. I suppose it is closely connected with the missing maximize/minimize function of JDialogs. On the other hand, creating a JFrame as subframe is not recommended.
** Edit 1 **
Here a test code:
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JTextPane;
import javax.swing.WindowConstants;
public class JDialogResizetest extends JFrame {
private JButton openButton;
public JDialogResizetest() {
openButton = new JButton();
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
getContentPane().setLayout(new FlowLayout());
openButton.setText("Open");
openButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
openButtonActionPerformed(evt);
}
});
getContentPane().add(openButton);
pack();
}
private void openButtonActionPerformed(ActionEvent evt) {
JDialog dialog = new JDialog(this, false);
dialog.getContentPane().add(new JTextPane());
dialog.setVisible(true);
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new JDialogResizetest().setVisible(true);
}
});
}
}
Here a picture of the desired behavior:

tooltipText bug causes JMenuItem to lose focus

I am working on a Java Swing GUI and am having a minor issue with tool tip text on popup menu items.
Basically when you hover over a JMenuItem it is supposed to leave that JMenuItem selected and display the desired tool tip text.
What actually happens is when the tool tip text is made visible a StateChange event seems to cause the relevant JMenuItem to lose selection status and so the tool tip text very quickly disappears. Note that this only happens the first time, if you move your mouse around you can get the JMenuItem to select again and it will also display the tool tip text properly. I could leave this but I was hoping to set a delay through the ToolTipManager's sharedInstance() which at this point would hurt the user-friendly side of things since the user would have to wait twice as long after realizing the issue themselves.
I built a very simple demo that reflects the problem I am seeing, am I missing something or is this just a Java 8 with Mac issue?
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class TestFrame {
static JFrame jf = new JFrame();
public static void main(String[] args){
jf = new JFrame();
JPanel jp = new JPanel();
jp.setBackground(Color.white);
jp.setForeground(Color.black);
JPopupMenu p = new JPopupMenu();
JMenuItem jmi = new JMenuItem("An option");
jmi.setToolTipText("mouse over text");
jmi.addChangeListener(new ChangeListener(){
#Override
public void stateChanged(ChangeEvent e) {
System.out.println("CHANGED by: "+e.getSource().toString());
}});
p.add(jmi);
jp.setComponentPopupMenu(p);
jf.add(jp);
jf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
jf.setSize(1000, 500);
jf.setPreferredSize(jf.getSize());
jf.setVisible(true);
}
}
For reference, I tried this modified version that runs on the event dispatch thread. It's seems improved, but it still fails intermittently. It looks like a regression.
Console:
$ javac TestFrame.java ; java TestFrame
1.8.0_31
10.9.5
…
Code:
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.event.ChangeEvent;
/** #see http://stackoverflow.com/a/28160300/230513 */
public class TestFrame {
public static void main(String[] args) {
System.out.println(System.getProperty("java.version"));
System.out.println(System.getProperty("os.version"));
EventQueue.invokeLater(() -> {
JFrame jf = new JFrame();
JPanel jp = new JPanel();
JPopupMenu p = new JPopupMenu();
JMenuItem jmi = new JMenuItem("An option");
jmi.setToolTipText("Mouse over text");
jmi.addChangeListener((ChangeEvent e) -> {
System.out.println("Changed by: " + e.getSource().toString());
});
p.add(jmi);
jp.setComponentPopupMenu(p);
jf.add(jp);
jf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
jf.pack();
jf.setSize(320, 240);
jf.setVisible(true);
});
}
}

How to get a JInternalFrame in the order i add it

I tried to access a JInternalFrame in my JDesktopPane and use getAllFrames method.
I just want to access the JInternalFrame in the order that i added into the JDesktopPane.
for example, i add a,b,c
frames[0] contain a
frames[1] contain b
frames[2] contain c
But i found out that the content in the array will change in case that i change my selection.
Every time I change my selection.
The selected JInternalFrame in the array will move to the top one.
For example , I select b
The array will become
frames[0] contain b
frames[1] contain a
frames[2] contain c
Are there any other ways to get the internal frame in the order i add it into desktoppane??
package org.app;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
public class MainFrame extends JFrame{
private static final long serialVersionUID = 1L;
private JDesktopPane theDesktop;
private List<JInternalFrame> frameList=new ArrayList<>();
public MainFrame() {
super("Internal Frame Demo");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(800,600);
this.setJMenuBar(setMenubar());
theDesktop=new JDesktopPane();
this.add(theDesktop);
this.setVisible(true);
}
public JMenuBar setMenubar() {
JMenuBar bar=new JMenuBar();
JMenu addMenu=new JMenu("Add");
JMenuItem newFrame=new JMenuItem("Internal Frame");
newFrame.addActionListener(new MenuAction());
addMenu.add(newFrame);
bar.add(addMenu);
return bar;
}
public JInternalFrame addInternalFrame() {
JInternalFrame jif=new JInternalFrame("Internal frame",true,true,true,true);
jif.setSize(new Dimension(240, 300));
jif.addInternalFrameListener(new InternalFrameAdapter() {
#Override
public void internalFrameClosing(InternalFrameEvent e){
frameList.remove(e.getInternalFrame());
System.out.println("from frame closing event");
}
});
jif.show();
return jif;
}
public JInternalFrame getInternalFrame(int index) {
return frameList.get(index);
}
class MenuAction implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
JInternalFrame f=addInternalFrame();
theDesktop.add(f);
frameList.add(f);
System.out.println("from menu action");
}
}
public static void main(String[] args){
new MainFrame();
}
}

Categories