How to get the currently selected Menu or MenuItem - java

How can I retrieve the currently selected menu or menu item when clicked on it and the subsequent path will be printed on console. In this code I have done the menus and sub menus up to 4 levels. And want to print the path of selected menus and submenus when clicked on. I am using swing concept for this program. Please help. Thanks in advance.
import java.awt.Component;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.MenuElement;
import javax.swing.MenuSelectionManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class Menu {
public static void main(final String args[]) {
JFrame frame = new JFrame("MenuSample Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JMenuBar menuBar = new JMenuBar();
JMenu worldMenu = new JMenu("world");
menuBar.add(worldMenu);
JMenu indMenu = new JMenu("India");
worldMenu.add(indMenu);
/* creates menu */
JMenu odMenu = new JMenu("Odisha");
indMenu.add(odMenu);
JMenu delhiMenu = new JMenu("Delhi");
indMenu.add(delhiMenu);
JMenu upMenu = new JMenu("Uttar Pradesh");
indMenu.add(upMenu);
JMenu mpMenu = new JMenu("Madhya Pradesh");
indMenu.add(mpMenu);
JMenu ausMenu = new JMenu("Australia");
worldMenu.add(ausMenu);
JMenu AmericaMenu = new JMenu("America");
worldMenu.add(AmericaMenu);
/* creates submenu */
JMenu bbMenu = new JMenu("Bhubaneswar");
odMenu.add(bbMenu);
JMenu bmMenu = new JMenu("Berhampur");
odMenu.add(bmMenu);
/*creates sub sub menu */
JMenuItem rjMenuItem = new JMenuItem("Raj Mahal");
bbMenu.add(rjMenuItem);
JMenuItem abMenuItem = new JMenuItem("Acharya Bihar");
bbMenu.add(abMenuItem);
JMenuItem bnMenuItem = new JMenuItem("Bani Bihar");
bbMenu.add(bnMenuItem);
/* retrieving path */
MenuSelectionManager.defaultManager().addChangeListener(
new ChangeListener() {
public void stateChanged(ChangeEvent evt) {
MenuElement[] path = MenuSelectionManager.defaultManager()
.getSelectedPath();
//
int s=0;
for (int i = 0; i < path.length; i++) {
Component c = path[i].getComponent();
if (c instanceof JMenuItem) {
JMenuItem mi = (JMenuItem) c;
String label = mi.getText();
System.out.println("LEVEL----" + s);
System.out.println("you hv selected:"+label);
s++;
}
}
}
});
//
frame.setJMenuBar(menuBar);
frame.setSize(350, 250);
frame.setVisible(true);
}
}

How to get the currently selected
Menu - A parent JMenu cannot be selected. Why would you want to know
if the mouse is over it?
MenuItem - Embrace the Action interface
It is an all too common oversight to not use the Action interface. When developing with Swing make Action your friend, it will treat you well. You went down the wrong path with MenuSelectionManager.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
public class MenuExample {
private JFrame frame;
private JLabel choiceIndicator;
MenuExample create() {
frame = createFrame();
choiceIndicator = new JLabel();
frame.setJMenuBar(createMenuBar());
frame.getContentPane().add(createContent());
return this;
}
private Component createContent() {
JPanel panel = new JPanel();
panel.add(new JLabel("Last menu item choice:"));
panel.add(choiceIndicator);
return panel;
}
private JMenuBar createMenuBar() {
JMenuBar menuBar = new JMenuBar();
menuBar.add(createWorld());
return menuBar;
}
private JMenu createWorld() {
JMenu worldMenu = new JMenu("World");
worldMenu.add(createIndia());
worldMenu.add(new JMenu("Australia"));
worldMenu.add(new JMenu("America"));
return worldMenu;
}
private JMenu createIndia() {
JMenu india = new JMenu("India");
india.add(createOdisha());
india.add(new JMenu("Delhi"));
india.add(new JMenu("Uttar Pradesh"));
india.add(new JMenu("Madhya Pradesh"));
return india;
}
private JMenuItem createOdisha() {
JMenu menu = new JMenu("Odisha");
menu.add(createBhubaneswar());
menu.add(new JMenu("Berhampur"));
return menu;
}
private JMenuItem createBhubaneswar() {
JMenu menu = new JMenu("Bhubaneswar");
menu.add(choiceItem("Raj Mahal"));
menu.add(choiceItem("Acharya Bihar"));
menu.add(choiceItem("Bani Bihar"));
return menu;
}
private JMenuItem choiceItem(String text) {
return new JMenuItem(new Choice(text, choiceIndicator));
}
private JFrame createFrame() {
JFrame frame = new JFrame(getClass().getSimpleName());
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
return frame;
}
void show() {
frame.setSize(350, 250);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new MenuExample().create().show();
}
});
}
class Choice extends AbstractAction {
private final JLabel choiceIndicator;
public Choice(String text, JLabel choiceIndicator) {
this(text, null, null, null, choiceIndicator);
}
public Choice(String text, ImageIcon icon, String desc, Integer mnemonic, JLabel choiceIndicator) {
super(text, icon);
putValue(SHORT_DESCRIPTION, desc);
putValue(MNEMONIC_KEY, mnemonic);
this.choiceIndicator = choiceIndicator;
}
public void actionPerformed(ActionEvent e) {
choiceIndicator.setText(e.getActionCommand());
}
}
}

Related

Is there a way to detect current selection in JPopupMenu (SelectionModel ChangeListener doesn't work)

I want to detect when selection changes inside a JPopupMenu. Not when a menu item is clicked, but when a menu item is selected (armed). With simpler words, I want to detect this:
The thing that should work is to add a ChangeListener to its SelectionModel, but it doesn't seem to respond to selection events:
public class PopupSelection extends JFrame {
private static final long serialVersionUID = 363879723515243543L;
public PopupSelection() {
super("something");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new FlowLayout());
JLabel label = new JLabel("right click me");
JPopupMenu menu = new JPopupMenu();
menu.getSelectionModel().addChangeListener(System.out::println);
JMenuItem menuItem1 = new JMenuItem("Item1");
JMenuItem menuItem2 = new JMenuItem("Item2");
JMenuItem menuItem3 = new JMenuItem("Item3");
menu.add(menuItem1);
menu.add(menuItem2);
menu.add(menuItem3);
label.setComponentPopupMenu(menu);
getContentPane().add(label);
setSize(400, 400);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new PopupSelection().setVisible(true));
}
}
Second thing I tried is with a PropertyChangeListener, but it does not work (does not detect this specific event) either:
menu.addPropertyChangeListener(System.out::println);
I know there is the alternative of adding a ChangeListener to each JMenuItem and each time iterate all components of the JPopupMenu in order to find which one is selected, but this is not a solution I want to follow since it will add unwanted complexity in my code.
So, is there a way to detect the selection?
In case of a XY problem, my final goal is to increase/decrease this scrollbar properly when user changes menu's selection with arrow buttons: ↑ ↓
Use change listener on button model of your items. Here is the solution:
import java.awt.Component;
import java.awt.FlowLayout;
import java.util.stream.Stream;
import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/**
* <code>PopupSelection</code>.
*/
public class PopupSelection extends JFrame {
private static final long serialVersionUID = 363879723515243543L;
public PopupSelection() {
super("something");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new FlowLayout());
JLabel label = new JLabel("right click me");
JPopupMenu menu = new MyPopupMenu();
menu.getSelectionModel().addChangeListener(System.out::println);
JMenuItem menuItem1 = new JMenuItem("Item1");
JMenuItem menuItem2 = new JMenuItem("Item2");
JMenuItem menuItem3 = new JMenuItem("Item3");
menu.add(menuItem1);
menu.add(menuItem2);
menu.add(menuItem3);
label.setComponentPopupMenu(menu);
getContentPane().add(label);
setSize(400, 400);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new PopupSelection().setVisible(true));
}
private static class MyPopupMenu extends JPopupMenu {
private final ChangeListener listener = this::changed;
#Override
protected void addImpl(Component comp, Object constraints, int index) {
super.addImpl(comp, constraints, index);
if (comp instanceof AbstractButton) {
((AbstractButton) comp).getModel().addChangeListener(listener);
}
}
#Override
public void remove(int index) {
Component comp = getComponent(index);
if (comp instanceof AbstractButton) {
((AbstractButton) comp).getModel().removeChangeListener(listener);
}
super.remove(index);
}
private void changed(ChangeEvent e) {
ButtonModel model = (ButtonModel) e.getSource();
AbstractButton selected = Stream.of(getComponents()).filter(AbstractButton.class::isInstance)
.map(AbstractButton.class::cast)
.filter(b -> b.getModel().isArmed() && b.getModel() == model).findAny().orElse(null);
setSelected(selected);
}
}
}
Instead of adding a ChangeListener to each JMenuItem, you might be able to add a ChangeListener to the MenuSelectionManager.
MenuSelectionManager.defaultManager().addChangeListener(e -> {
Object o = e.getSource();
if (o instanceof MenuSelectionManager) {
MenuSelectionManager m = (MenuSelectionManager) o;
printMenuElementArray(m.getSelectedPath());
}
});
PopupSelection2.java
import java.awt.*;
import javax.swing.*;
public class PopupSelection2 extends JFrame {
public PopupSelection2() {
super("something");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new FlowLayout());
JLabel label = new JLabel("right click me");
JPopupMenu menu = new JPopupMenu();
menu.getSelectionModel().addChangeListener(System.out::println);
JMenuItem menuItem1 = new JMenuItem("Item1");
JMenuItem menuItem2 = new JMenuItem("Item2");
JMenuItem menuItem3 = new JMenuItem("Item3");
menu.add(menuItem1);
menu.add(menuItem2);
menu.add(menuItem3);
label.setComponentPopupMenu(menu);
MenuSelectionManager.defaultManager().addChangeListener(e -> {
Object o = e.getSource();
if (o instanceof MenuSelectionManager) {
MenuSelectionManager m = (MenuSelectionManager) o;
printMenuElementArray(m.getSelectedPath());
}
});
getContentPane().add(label);
setSize(400, 400);
setLocationRelativeTo(null);
}
// #see javax/swing/MenuSelectionManager.java
private static void printMenuElementArray(MenuElement[] path) {
System.out.println("Path is(");
for (int i = 0, j = path.length; i < j ; i++) {
for (int k = 0; k <= i; k++) {
System.out.print(" ");
}
MenuElement me = path[i];
if (me instanceof JMenuItem) {
System.out.println(((JMenuItem)me).getText() + ", ");
} else if (me instanceof JMenuBar) {
System.out.println("JMenuBar, ");
} else if (me instanceof JPopupMenu) {
System.out.println("JPopupMenu, ");
} else if (me == null) {
System.out.println("NULL , ");
} else {
System.out.println("" + me + ", ");
}
}
System.out.println(")");
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new PopupSelection2().setVisible(true));
}
}

Updating JPanel from external class will just add another one but dont replace it

My main Java program (MyFrame) should update an existing ContentPanel in its JFrame with an other JPanel initiated by an other class (MyPanel) depending on what JMenuItem is clicked and a parameter for the new JPanel will be passed. When I click the JMenuItem, the JPanel dont update, it is behind the first one and not in foreground until I resize the window. Please can you help me solve this?
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
public class MyFrame extends JFrame {
private Container contentContainer;
public static void main(String[] args) {
new MyFrame();
}
public MyFrame() {
setTitle("MyFrame");
setSize(300, 200);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setJMenuBar(createMenu());
MyPanel panel = makePanel(new String("Test oO"));
contentContainer = this.getContentPane();
setVisible(true);
}
public JMenuBar createMenu() {
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("Menu");
JMenuItem menuItem = new JMenuItem("Test");
menuItem.setMnemonic(KeyEvent.VK_E);
menuItem.setToolTipText("Test");
menuItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
MyPanel dynamicPanel = makePanel(new String("Test"));
contentContainer.add(dynamicPanel);
contentContainer.revalidate();
contentContainer.repaint();
}
});
menu.add(menuItem);
JMenuItem menuItem1 = new JMenuItem("Test 1");
menuItem1.setMnemonic(KeyEvent.VK_E);
menuItem1.setToolTipText("Test 1");
menuItem1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
MyPanel dynamicPanel1 = makePanel(new String("Test 1"));
contentContainer.add(dynamicPanel1);
revalidate();
repaint();
}
});
menu.add(menuItem1);
JMenuItem menuItem2 = new JMenuItem("Dialog");
menuItem2.setMnemonic(KeyEvent.VK_E);
menuItem2.setToolTipText("Dialog");
menuItem2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
makeDialog(new String("Zur Info"), new String("Du hast Edit geklickt"));
}
});
menu.add(menuItem2);
menuBar.add(menu);
return menuBar;
}
public JDialog makeDialog(String title, String content) {
JDialog meinJDialog = new JDialog();
meinJDialog.setTitle(title);
JTextArea contentArea = new JTextArea(content);
contentArea.setEditable(false);
meinJDialog.add(contentArea);
meinJDialog.setSize(200,200);
meinJDialog.setModal(true);
meinJDialog.setLocationRelativeTo(null);
meinJDialog.setVisible(true);
return meinJDialog;
}
public MyPanel makePanel(String config) {
MyPanel panel = new MyPanel(config);
panel.revalidate();
panel.repaint();
return panel;
}
}
class MyPanel extends JPanel {
public MyPanel(String config) {
JButton testButton = new JButton(config);
add(testButton);
setVisible(true);
revalidate();
repaint();
return;
}
}
When I add removeAll calls, it seems to work.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class MyFrame extends JFrame {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new MyFrame();
}
});
}
private final Container contentContainer;
public MyFrame() {
setTitle("MyFrame");
setSize(300, 200);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setJMenuBar(createMenu());
contentContainer = getContentPane();
contentContainer.add(new MyPanel("Test oO"));
setVisible(true);
}
public JMenuBar createMenu() {
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("Menu");
JMenuItem menuItem = new JMenuItem("Test");
menuItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
MyPanel dynamicPanel = new MyPanel("Test");
contentContainer.removeAll();
contentContainer.add(dynamicPanel);
contentContainer.revalidate();
contentContainer.repaint();
}
});
menu.add(menuItem);
JMenuItem menuItem1 = new JMenuItem("Test 1");
menuItem1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
contentContainer.removeAll();
contentContainer.add(new MyPanel("Test 1"));
contentContainer.revalidate();
contentContainer.repaint();
}
});
menu.add(menuItem1);
menuBar.add(menu);
return menuBar;
}
}
class MyPanel extends JPanel {
public MyPanel(String config) {
JButton testButton = new JButton(config);
add(testButton);
setVisible(true);
revalidate();
repaint();
}
}
I also wrapped your main method in an EventQueue.invokeLater call to make sure all Swing operations happen on the EDT
I removed all the code related to the dialog, as this was unneeded to demonstrate the problem. Inlined some other methods to reduce the length of the code snippet further
And the golden tip if you need to debug situations like that: press ctrlshiftF1 when your JFrame is focused. This will print out the Swing hierarchy of that component. Doing this with your original code clearly shows that the content pane contains multiple MyPanel instances.

Set size on component in JPanel

I am new for Java. I have searched how to set the size of the JTextField and JButton, but I still cannot make it work. Hope someone tell me how to solve it. I declare the height and width, but the component seems doesn't take it. The JTextField and JButton with red & yellow background should be same height. Also the JTextField width is very long.
There is my code:
package MyPackage;
import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.filechooser.*;
import java.io.*;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.*;
import javax.swing.JButton;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.ComponentOrientation;
import javax.swing.JTextField;
public class MainForm extends JFrame implements ActionListener {
private PDFNotesBean PDFNotesBean = null;
private JMenuItem cascade = new JMenuItem("Cascade");
private int numInterFrame=0;
private JDesktopPane desktop=null;
private ArrayList<File> fileList=new ArrayList<File>();
private static int categoryButtonWidth= 40;
private static int categoryTextFieldWidth=60;
private static int categoryHight=40;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run()
{
new MainForm();
}
});
}
public MainForm(){
super("Example");
//it is equal to this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
// Name the JMenu & Add Items
JMenu menu = new JMenu("File");
menu.add(makeMenuItem("Open"));
menu.add(makeMenuItem("Save"));
menu.add(makeMenuItem("Quit"));
// Add JMenu bar
JMenuBar menuBar = new JMenuBar();
menuBar.add(menu);
//menuBar.add(menuWindow);
setJMenuBar(menuBar);
this.setMinimumSize(new Dimension(400, 500));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setExtendedState(JFrame.MAXIMIZED_BOTH);
desktop = new JDesktopPane();
this.setLayout(new BorderLayout());
setCategoryPanel();
this.add(desktop, BorderLayout.CENTER);
setVisible(true);
}
private void setCategoryPanel(){
//set the color label category
JPanel panelCategory=new JPanel();
panelCategory.setLayout(new BoxLayout(panelCategory, BoxLayout.LINE_AXIS));
JButton btnCategory_1=new JButton("");
btnCategory_1.setPreferredSize(new Dimension ( categoryButtonWidth, categoryHight));
btnCategory_1.setBackground(Color.red);
btnCategory_1.addActionListener(this);
panelCategory.add(btnCategory_1);
JTextField txtCategory_1 = new JTextField();
txtCategory_1.setPreferredSize(new Dimension (categoryTextFieldWidth, categoryHight));
panelCategory.add(txtCategory_1);
JButton btnCategory_2=new JButton("");
btnCategory_2.setPreferredSize(new Dimension ( categoryButtonWidth, categoryHight));
btnCategory_2.setBackground(Color.YELLOW);
btnCategory_2.addActionListener(this);
panelCategory.add(btnCategory_2);
JTextField txtCategory_2 = new JTextField( );
txtCategory_1.setPreferredSize(new Dimension (categoryTextFieldWidth, categoryHight));
panelCategory.add(txtCategory_2);
this.add(panelCategory, BorderLayout.NORTH);
}
public void actionPerformed(ActionEvent e) {
// Menu item actions
String command = e.getActionCommand();
if (command.equals("Quit")) {
System.exit(0);
} else if (command.equals("Open")) {
// Open menu item action
JFileChooser fileChooser = new JFileChooser();
int returnVal = fileChooser.showOpenDialog(MainForm.this);
if (returnVal == fileChooser.APPROVE_OPTION) {
numInterFrame=numInterFrame+1;
File file = fileChooser.getSelectedFile();
fileList.add(file);
AddNote(file);
// Load file
} else if (returnVal == JFileChooser.CANCEL_OPTION ) {
// Do something else
}
}
else if (command.equals("Save")) {
// Save menu item action
System.out.println("Save menu item clicked");
}
}
private JMenuItem makeMenuItem(String name) {
JMenuItem m = new JMenuItem(name);
m.addActionListener(this);
return m;
}
private void AddNote(File file){
JInternalFrame internalFrame = new JInternalFrame("PDFAnnotation"
+ file.getName(), true, true, true, true);
internalFrame.setBounds(0, 0, 600, 100);
desktop.add(internalFrame);
PDFPanel p=new PDFPanel();
JPanel e =p.getJPanel(file);
internalFrame.add(e, BorderLayout.CENTER);
internalFrame.setVisible(true);
this.add(desktop, BorderLayout.CENTER);
//resize the internal frame as full screen
Dimension size = desktop.getSize();
int w = size.width ;
int h = size.height ;
int x=0;
int y=0;
desktop.getDesktopManager().resizeFrame(internalFrame, x, y, w, h);
}
}
Don't use the setPreferredSize() method.
All Swing components will have a preferred size.
For a JTextField you can use:
JTextField textField = new JTextField(5);
to indication how many characters you want to display at one time.
For the JButton, the width is determined by the text you add to the button.
When you use a BoxLayout, the width of the components is increased to fill the available space.
Just use a FlowLayout (which is the default for a JPanel) and the components will be displayed at their preferred sizes.

JInternalFrame is not show

I am new for Java. I need to have MDI in my project. When the user clicks ‘Open’ in menu bar, the internal frame is added and should be full screen on top.
I still cannot make it full screen on top when it is open. Also in my code, if I remove the following line from “AddNote” method, I cannot see the internal frame. In logic the JDesktop should add when the form is open.
JDesktopPane desktop = new JDesktopPane();
There is my code:
package MyPackage;
import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.filechooser.*;
import java.io.*;
import java.awt.Dimension;
import java.awt.FlowLayout;
public class MainForm extends JFrame implements ActionListener {
private JMenuItem cascade = new JMenuItem("Cascade");
private int numInterFrame=0;
private JDesktopPane desktop=null;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run()
{
new MainForm();
}
});
}
public MainForm(){
super("Example");
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
// Name the JMenu & Add Items
JMenu menu = new JMenu("File");
menu.add(makeMenuItem("Open"));
menu.add(makeMenuItem("Save"));
menu.add(makeMenuItem("Quit"));
// Add JMenu bar
JMenuBar menuBar = new JMenuBar();
menuBar.add(menu);
//menuBar.add(menuWindow);
setJMenuBar(menuBar);
this.setMinimumSize(new Dimension(400, 500));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(new BorderLayout());
this.setExtendedState(JFrame.MAXIMIZED_BOTH);
JDesktopPane desktop = new JDesktopPane();
this.add(desktop, BorderLayout.CENTER);
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
// Menu item actions
String command = e.getActionCommand();
if (command.equals("Quit")) {
System.exit(0);
} else if (command.equals("Open")) {
// Open menu item action
JFileChooser fileChooser = new JFileChooser();
int returnVal = fileChooser.showOpenDialog(MainForm.this);
if (returnVal == fileChooser.APPROVE_OPTION) {
numInterFrame=numInterFrame+1;
File file = fileChooser.getSelectedFile();
AddNote(numInterFrame);
// Load file
} else if (returnVal == JFileChooser.CANCEL_OPTION ) {
// Do something else
}
}
else if (command.equals("Save")) {
// Save menu item action
System.out.println("Save menu item clicked");
}
}
private JMenuItem makeMenuItem(String name) {
JMenuItem m = new JMenuItem(name);
m.addActionListener(this);
return m;
}
private void AddNote(int index){
JDesktopPane desktop = new JDesktopPane();
JInternalFrame internalFrame = new JInternalFrame("PDFAnnotation" + index, true, true, true, true);
internalFrame.setBounds(0, 0, 600, 100);
desktop.add(internalFrame);
PDFPanel p=new PDFPanel();
JPanel e =p.getJPanel();
internalFrame.add(e, BorderLayout.CENTER);
internalFrame.setVisible(true);
this.add(desktop, BorderLayout.CENTER);
/* Dimension size = desktop.getSize();
int w = size.width ;
int h = size.height ;
int x=0;
int y=0;
desktop.getDesktopManager().resizeFrame(internalFrame, x, y, w, h);*/
}
}
There are a number problems, which are compounded based on the fact that you are shadowing the main desktop variable...
You declare an instance field....
private JDesktopPane desktop = null;
But in your constructor, you declare it again...
JDesktopPane desktop = new JDesktopPane();
This means that the instance field remains null. Instead, in you constructor, you should be using the instance field, for example...
desktop = new JDesktopPane();
This means that in your AddNote method, you can get rid of the creation of yet another JDesktopPane...
//JDesktopPane desktop = new JDesktopPane();
JInternalFrame internalFrame = new JInternalFrame("PDFAnnotation" + index, true, true, true, true);
internalFrame.setBounds(0, 0, 600, 100);
desktop.add(internalFrame);
PDFPanel p = new PDFPanel();
JPanel e = p.getJPanel();
internalFrame.add(e, BorderLayout.CENTER);
internalFrame.setVisible(true);
//this.add(desktop, BorderLayout.CENTER);
Also, because you're using...
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
You won't need
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
You should also have a read of Code Conventions for the Java Programming Language

JTabbedPane does not add more than 1 tab when using .addTab()

I am wondering why the JTabbedPane only adds 1 tab. When I use the method addTab and then reuse it to create a new tab, it overrides the first tab created. Here is the code: BTW, most of the code that might be related to the problem is at actionlistener.
package com.james.client;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.filechooser.FileFilter;
import javax.swing.text.Element;
public class Main extends JFrame {
private static final long serialVersionUID = 1L;
public static void main(String [] args)
{
//JTextArea
final JTextArea code = new JTextArea();
final JTextArea lines = new JTextArea("1");
final JScrollPane scroll = new JScrollPane(code);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
lines.setBackground(Color.LIGHT_GRAY);
lines.setEditable(false);
code.getDocument().addDocumentListener(new DocumentListener(){
public String getText(){
int caretPosition = code.getDocument().getLength();
Element root = code.getDocument().getDefaultRootElement();
String text = "1" + System.getProperty("line.separator");
for(int i = 2; i < root.getElementIndex( caretPosition ) + 2; i++){
text += i + System.getProperty("line.separator");
}
return text;
}
#Override
public void changedUpdate(DocumentEvent de) {
lines.setText(getText());
}
#Override
public void insertUpdate(DocumentEvent de) {
lines.setText(getText());
}
#Override
public void removeUpdate(DocumentEvent de) {
lines.setText(getText());
}
});
scroll.getViewport().add(code);
scroll.setRowHeaderView(lines);
//JFrame
JFrame window = new JFrame("MinecraftProgrammer++");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(1000, 700);
window.setResizable(false);
window.setLocationRelativeTo(null);
//JMenuBar
JMenuBar menu = new JMenuBar();
JMenu file = new JMenu("File");
JMenu newfile = new JMenu("New");
//JTabbedPane
final JTabbedPane tabs = new JTabbedPane();
tabs.setBackground(Color.gray);
//JMenu items
JMenuItem classfile = new JMenuItem("Class");
JMenuItem packagefolder = new JMenuItem("Package");
JMenuItem other = new JMenuItem("Other");
JMenuItem open = new JMenuItem("Open");
open.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
try {
JFileChooser chooseFile = new JFileChooser();
chooseFile.setAcceptAllFileFilterUsed(false);
FileFilter filter1 = new ExtensionFileFilter("Java Class", new String[] {"JAVA"});
FileFilter filter2 = new ExtensionFileFilter("Text File", new String[] {"TXT"});
chooseFile.setFileFilter(filter2);
chooseFile.setFileFilter(filter1);
chooseFile.showOpenDialog(chooseFile);
String filePath = chooseFile.getSelectedFile().getAbsolutePath();
FileReader readFile = new FileReader(filePath);
String fileName = chooseFile.getSelectedFile().getName();
tabs.addTab(fileName, scroll);
#SuppressWarnings("resource")
Scanner fileReaderScan = new Scanner(readFile);
String storeAllString = "";
while(fileReaderScan.hasNextLine())
{
String temp = fileReaderScan.nextLine() + "\n";
storeAllString = storeAllString + temp;
}
code.setText(storeAllString);
code.setLineWrap(true);
code.setWrapStyleWord(true);
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println(e);
}
}
});
JMenuItem save = new JMenuItem("Save");
JMenuItem saveas = new JMenuItem("Save As...");
//Compile menu bar
file.add(newfile);
file.add(open);
file.add(save);
file.add(saveas);
newfile.add(classfile);
newfile.add(packagefolder);
newfile.add(other);
menu.add(file);
window.add(tabs);
window.setJMenuBar(menu);
window.setVisible(true);
}
}
You're adding the JScrollPane "scroll" to the JTabbedPane. How many times do you construct this component? Answer -- once only. So you're only adding and re-adding the same component every time.
final JScrollPane scroll = new JScrollPane(code); // here you create scroll
// .....
open.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
try {
JFileChooser chooseFile = new JFileChooser();
// ....
// you add the same component here
tabs.addTab(fileName, scroll);
// ....
}
Since you can't add a component to a container more than once and see it in both containers, the solution is to create any components needed for the new tab inside of the ActionListener's actionPerformed(...) method each time you need to add something to the JTabbedPane.

Categories