Java: Difficulty with Swing - java

I'm trying to modify a GUI. It is hosting a GLCanvas displaying JOGL content.
Here is the code to set it up:
private void setupWindow() {
this.frame = new JFrame(WINDOW_TITLE);
frame.setSize(width, height);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("File");
menuBar.add(menu);
JMenuItem exitItem = new JMenuItem("Exit");
exitItem.addActionListener(listener);
menu.add(exitItem);
frame.setJMenuBar(menuBar);
}
Currently, the canvas takes up the entire space in the window, aside from the menu bar. I'd like to make space for other controls in the window, like buttons and list boxes. How can I do it?
I tried inserting the following, but it didn't work:
private void setupWindow() {
this.frame = new JFrame(WINDOW_TITLE);
frame.setSize(width, height);
// ** inserted the following:
JPanel canvasPanel = new JPanel(new BorderLayout());
canvasPanel.add(canvas);
canvasPanel.setSize(30, 40);
canvasPanel.setVisible(true);
// **
frame.add(canvasPanel);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("File");
menuBar.add(menu);
JMenuItem exitItem = new JMenuItem("Exit");
exitItem.addActionListener(listener);
menu.add(exitItem);
frame.setJMenuBar(menuBar);
}
This doesn't modify the appearance of the window at all.
What should I be doing here? I'm not too familiar with Java GUIs.
Update: Changing the constructor's argument from BorderLayout to FlowLayout causes the GLCanvas to disappear.

Per Anon's answer, you really need to better understand the layout managers. Your question is too open ended.
In case this helps though:
JPanel canvasPanel = new JPanel(new BorderLayout());
frame.add(canvasPanel, BorderLayout.CENTER);
canvasPanel.add(canvas);
Box leftBtnsBox = Box.createVerticalBox();
frame.add(leftBtns, BorderLayout.WEST);
leftBtns.add(new JButton("Button 1"));
leftBtns.add(new JButton("Button 2"));
This code sets a BordeLayout explicitly, but I think the default layout manager for panels (and content panes) is BorderLayout. This code will put two buttons to the top left of the canvas panel arranged vertically. Because you are using these layout managers, your second code example's setSize had no effect.

I suggest checking out this guide to layout managers - it will give you enough info to see what you should try.

Related

Separating code into classes (GUI specific) using Java

In a sample program I have one class that places:
GUI components on a JPanel which is inside a JFrame.
A method makeMenu to create a menu bar
An ActionListener inside the makeMenu method to change the JPanels background color when called.
Main method.
public class GUI extends JFrame {
private JPanel jPanelRight;
private JPanel jPanelLeft;
JMenuBar menuBar;
JMenu file, help;
JMenuItem changeColor;
public GUI() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setJMenuBar(makeMenu()); // call constructor to create the menu
this.setSize(800, 600); // set frame size
this.setVisible(true); // display frame
this.setTitle("understanding objects");
setLayout(new BorderLayout()); // layout manager
jPanelLeft = new JPanel(); //left jpanel
jPanelLeft.setPreferredSize(new Dimension(400, 800)); // to set the size of the left panel
jPanelLeft.setBackground(Color.blue);
jPanelRight = new JPanel(); //right jpanel
jPanelRight.setPreferredSize(new Dimension(400, 600)); // to set the size of the right panel
jPanelRight.setBackground(Color.green);
this.add(jPanelLeft, BorderLayout.WEST); //add jpanel to the left side of the frame
this.add(jPanelRight, BorderLayout.EAST); //add jpanel to the right side of the frame
}//end constructor
public JMenuBar makeMenu() {
menuBar = new JMenuBar(); //menu bar
file = new JMenu("File"); //menu item
menuBar.add(file);
help = new JMenu("Help"); //menu item
menuBar.add(help);
changeColor = new JMenuItem("Change Colour"); //sub menu item
changeColor.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
jPanelRight.setBackground(Color.red);
}
});
file.add(changeColor);
return menuBar;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new GUI();
}
});
} // end
}//end class
I am trying to separate the code into 3 or 4 classes.
GUI class
ActionListener class
MakeMenu class
Main class (to run program)
one problem that keeps occurring is that i when i separate the code i can only change using System.out.println(); and can not change the GUI i.e. i can print out that the jPanelRight is now red but can not actually change the jPanelRight to red.
I am possibly going about this the wrong way.
A GUI to use a different class to create its menu and another different class to control the actions for the GUI's menu.

Expand JMenu to left, while retaining default text alignment

I have a JMenu A within a JMenuBar aligned to the right of the screen. Within this menu are several JMenuItems, along with another JMenu B. Since menu A is right aligned, I need menu B to open to the left. In order to do this I found the code
setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);.
The issue however, is that this messes with the text alignment of menu 2, which I would like to stay exactly like the other menu items.
I have also tried manually aligning menu 2 using SwngConstants.leftAlign, however this is too severe:
How can I make the menu expand to the left, while retaining the default text alignment? Thanks in advance! The code I used to produce the above images is seen below:
import java.awt.*;
import javax.swing.*;
public class Test{
public Test(){
JFrame frame = new JFrame();
JMenuBar menuBar = new JMenuBar();
JMenu menu1 = new JMenu("Menu 1");
JMenu menu2 = new JMenu("Menu 2");
JMenuItem menuitem1 = new JMenuItem("Menu Item 1");
JMenuItem menuitem2 = new JMenuItem("Menu Item 2");
JMenuItem menuitem3 = new JMenuItem("Menu Item 3");
JMenuItem menuitem4 = new JMenuItem("Menu Item 4");
menuBar.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
menu1.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
menu2.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
menu2.setHorizontalAlignment(SwingConstants.LEFT);
menuBar.add(menu1);
menu1.add(menuitem1);
menu1.add(menuitem2);
menu1.add(menu2);
menu2.add(menuitem3);
menu2.add(menuitem4);
frame.setJMenuBar(menuBar);
frame.getContentPane().setBackground(Color.WHITE);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(270,170));
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args){
try{
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
UIManager.getLookAndFeelDefaults().put("Label.font", new Font("Arial", Font.PLAIN, 12));
UIManager.getLookAndFeelDefaults().put("Button.font", new Font("Arial", Font.PLAIN, 12));
UIManager.getLookAndFeelDefaults().put("ComboBox.font", new Font("Arial", Font.PLAIN, 12));
UIManager.getLookAndFeelDefaults().put("JTextField.font", new Font("Arial", Font.PLAIN, 12));
new Test();
} catch(Exception e){
JOptionPane.showConfirmDialog(null, e.getMessage());
}
}
}
UPDATE: If I remove the lines of code aligning the menus right to left and move the frame to the edge of the display screen, then the menus act as desired (i.e. the menu will not expand off the monitor). Perhaps there is a way to tell the menu not to expand off the JFrame rather than the monitor?
UPDATE: Thank you #StanislavL for the idea. Overriding menu 2 with the following code does the trick, it also gets rid of that unsightly overlap between the two menus. Note that menu 2 no longer needs ComponentOrientation.RIGHT_TO_LEFT.
JMenu menu2 = new JMenu("Menu 2"){
protected Point getPopupMenuOrigin(){
return new Point(-this.getPopupMenu().getPreferredSize().width, 0);
}
};
You can try to override
public ComponentOrientation getComponentOrientation()
method of JMenu to return your alignmnet
or JMenu has method you can override
protected Point getPopupMenuOrigin()

Java Swing and Mac view

I'm training with Java and Swing, in Windows the GUI is shown correctly, instead on MAC there are several problems.
The JMenuBar is shown in the window, while should be shown in the MAC bar [finder].
Code of JMenuBar:
JMenuBar menuBar = new JMenuBar();
preferenceItem.addMouseListener(this);
printItem.addMouseListener(this);
menuBar.add(fileMenu);
fileMenu.add(openItem);
fileMenu.add(printItem);
fileMenu.add(exportItem);
menuBar.add(optionMenu);
optionMenu.add(preferenceItem);
setJMenuBar(menuBar);
Than another problem is how two panels are shown. As you can see in the previous image backup button, which is in the second panel is shown above the first panel.
public OptionDialog(){
super();
setTitle(NOME_APPLICAZIONE);
Dimension dimensioni = Toolkit.getDefaultToolkit().getScreenSize();
setLocation((int)(dimensioni.getWidth()/2-getWidth()/2), (int)(dimensioni.getHeight()/2-getHeight()/2));
this.setVisible(true);
this.add(pnlDialog, BorderLayout.NORTH);
this.add(pnlDialogBackup, BorderLayout.SOUTH);
pnlDialog.setBorder(general);
GridLayout grid = new GridLayout(7,2,20,5);
pnlDialog.setLayout(grid);
pnlDialog.add(lblLingua);
pnlDialog.add(Language);
pnlDialog.add(lblCarattere);
pnlDialog.add(Char);
pnlDialog.add(lblOrdinamento);
pnlDialog.add(Order);
pnlDialog.add(lblScadenza);
pnlDialog.add(Scadenza);
pnlDialog.add(lblNotifica);
pnlDialog.add(Notifica);
pnlDialog.add(lblTempo);
pnlDialog.add(Time);
pnlDialog.add(Applica,BorderLayout.PAGE_END);
pnlDialogBackup.setBorder(backup);
pnlDialogBackup.add(Backup);
Notifica.addItemListener(this);
lblTempo.setVisible(false);
Time.setVisible(false);
setSize(new Dimension(300, 300));
setResizable(false);
}

JMenuBar not showing

I am trying to get my JMenuBar to display in the GUI, however it just appears as a 1-pixel line at the top.
This is my code...
public LibraryView() {
setBounds(100,100,640,480);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
JMenuBar b1 = new JMenuBar();
JMenu m1 = new JMenu("Test");
JMenuItem i1 = new JMenuItem("Item1");
this.setJMenuBar(b1);
}
Could someone please help me to understand what is wrong.
You need to add the JMenu and JMenuItem to the JMenuBar. You also need to pack() and setVisible(true); at the end of the method, just before the GUI is shown...
public LibraryView() {
setBounds(100,100,640,480);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
JMenuBar b1 = new JMenuBar();
JMenu m1 = new JMenu("Test");
JMenuItem i1 = new JMenuItem("Item1");
m1.add(i1); // ADDED
b1.add(m1); // ADDED
this.setJMenuBar(b1);
pack(); // ADDED
setVisible(true); // MOVED
}
You should call setVisible(true) only after adding all components to the top level window. Also don't forget to use layout managers, to let these managers and your component's preferredSize set the sizes of components, and don't forget to call pack().
call repaint() right before you call set visible(true) this NEVER FAILS.
setJMenuBar(menuBar);
menuBar.add(jMenuItem);
repaint(); //then
setVisible(true); //Assured NEVER FAILS

Swing: Showing a transparent Panel hovering over another Panel

I want to show a textArea showing some text (will show log lines) , and have an animated gif hoovering above it. I tried the solution described here , but all I get is a grey screen. Hints?
public class TestLayeredPanes {
private JFrame frame = new JFrame();
private JLayeredPane lpane = new JLayeredPane();
public TestLayeredPanes() {
frame.setPreferredSize(new Dimension(600, 400));
frame.setLayout(new BorderLayout());
frame.add(lpane, BorderLayout.CENTER);
//Build the animated icon
JLabel buildingIcon = new JLabel();
buildingIcon.setIcon(new ImageIcon(this.getClass().getResource(
"/com/ct/tasks/cmviewer/gui/progress_bar.gif")));
JPanel iconPanel = new JPanel();
iconPanel.add(buildingIcon);
//Build the textArea
JTextArea textLog = new JTextArea("Say something");
JPanel textPanel = new JPanel();
textPanel.add(new JScrollPane(textLog));
//Add the panels to the layered pane
lpane.add(textPanel, 0);
lpane.add(iconPanel, 1);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
new TestLayeredPanes();
}
}
Try putting your animated GIF on the glass pane of your root pane:
http://download.oracle.com/javase/tutorial/uiswing/components/rootpane.html
JXLayer make easier to do that. Look at JXLayer samples.
You also can take a look at code of XSwingX
Since you started with a working example, why did you remove lines of code from the example you copied?
Layered panes don't use a layout manager therefore the size of your components are (0, 0), so there is nothing to display. The setBounds(...) method in the example are there for a reason.

Categories