Opening a textpane in the same form on a Button click - java

I am trying to design a basic editor type of GUI in Java using Swing. I have a menu item named New clicking on which I want a blank text area to fill up the GUI. My code is as folows :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class UI extends JFrame {
private JMenuBar bar;
private JMenu menu;
private JMenuItem item;
private JTextPane tp;
public UI() {
setLayout(new FlowLayout());
bar = new JMenuBar();
setJMenuBar(bar);
menu = new JMenu("File");
bar.add(menu);
item = new JMenuItem("New");
menu.add(item);
item.addActionListener(new xyz());
}
public class xyz implements ActionListener {
public void actionPerformed(ActionEvent arg0) {
JTextPane tp = new JTextPane();
add(tp);
}
}
public static void main(String args[]) {
// do the rest of the stuffs
}
}
However, even on clicking on the New, I do not get the textPane on the same frame. Can someone please explain.

use JTextPane#setText("") instead of to create a new JTextPane
otherwise you have to notify Container with (re)validate() and repaint()

The text-panes should probably be added to a JTabbedPane if this app. supports multiple documents. If it is intended for 'single document', put the text pane onto the frame at start-up.

Related

How to use DefaultEditorKit in an AbstractAction

My notepad program that I'm writing uses AbstractActions for each item in the JMenuBar, and I want to keep it consistent that way throughout my code. And now I'm implementing Cut, Copy, Paste into the program but I'm unsure of how to do that with Action.
import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.text.DefaultEditorKit;
public class Home {
static Action Cut = new AbstractAction("Cut-Action") {
public void actionPerformed(ActionEvent e) {
// Where I want to use cut
new DefaultEditorKit.CutAction();
}
};
static public JMenuBar createMenuBar() {
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("Edit");
menu.add(Cut); // Adds the cut action
// adds the non-action method
JMenuItem item = new JMenuItem(new DefaultEditorKit.CutAction());
item.setText("Cut-NonAction");
menu.add(item);
menuBar.add(menu);
return menuBar;
}
public static void main(String[] args) {
JFrame frame = new JFrame("Home");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JMenuBar menuBar = createMenuBar();
frame.add(menuBar, BorderLayout.NORTH);
JTextPane txt = new JTextPane();
JScrollPane s = new JScrollPane(txt);
frame.add(s, BorderLayout.CENTER);
frame.setSize(400, 300);
frame.setVisible(true);
}
}
How would I be able to use the cut action in my abstract action??
I figured it out with a little bit of trial and error.
I changed this code:
public void actionPerformed(ActionEvent e) {
new DefaultEditorKit().CutAction();
}
to:
public void actionPerformed(ActionEvent e) {
Action cut = new DefaultEditorKit.CutAction();
cut.actionPerformed(e);
}
How would I be able to use the cut action in my abstract action??
Why are you trying to do this? The is not the way to use the Actions from the editor kit.
This is the proper way to use the actions:
JMenuItem item = new JMenuItem(new DefaultEditorKit.CutAction());
Or if you happen to need the CutAction on a menu and on a toolbar you would use code like:
Action cut = new DefaultEditorKit.CutAction();
cut.putValue(Action.NAME, "Cut");
JMenuItem cutMenuItem = new JMenuItem( cut );
JButton cutButton = new JButton( cut );
Now the same Action is shared which means you can enable/disable the Action and both components will be affected. Read the section from the Swing tutorial on How to Use Actions for more information and examples.

java JMenuBar not visible? Why?

I cannot figure out why my menu bar isn't visible. I have following code:
//Main
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class Menu extends JFrame{
public static void main(String[] args){
JFrame frame = new JFrame();
frame.setSize(500,350);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
menuBar mbObj = new menuBar();
mbObj.menuBar(frame);
}
}
//Menu Bar class
public class menuBar{
private JMenu file,edit;
private JMenuItem nFile ,oFile,sFile,saFile,exit;
private JMenuItem undo,copy,paste;
private JMenuBar bar;
public void menuBar(JFrame frame){
bar = new JMenuBar();
frame.setJMenuBar(bar);
bar.setVisible(true);
file = new JMenu("File");
edit = new JMenu("Edit");
bar.add(file);
bar.add(edit);
}
}
Call setVisible(true) on the top-level window, here a JFrame, only after adding all components, including the JMenuBar. You will also want to avoid calling setSize(...) on anything, and instead use layout managers and call pack() on the JFrame after adding all components and before calling setVisible(true).
So the order should be:
// create JFrame
JFrame frame = new JFrame("Foo");
// here add all components to the JFrame
// .....
// done adding components
frame.pack();
// frame.setLocationRelativeToPlatform(true); // if you wish
frame.setVisible(true);
As an aside class names should begin with an upper case letter, and dont have methods with the exact same name as the class, as that creates a "pseudo"-constructor and will confuse everyone.

ColorChooser by clicking JMenu Item

I tried codes from different site's and one from here about a color. How do I get color chooser to work with the press of a jmenu item?
I looked at ColorChooser Example and also Oracle Color Chooser Example and then implementing into the original class using the following code:
JMenuItem clr = new JMenuItem("Font Color");
clr.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
ColorChooserDemo ccd = new ColorChooserDemo();
ccd.setVisible(true);
}
});
But this seems do do nothing when I press the menu item.
The class code is from the oracle webpage. These are the following class I use (shortened of course to the problem at hand). I'm making a notepad program as i'm getting back into programming and refreshing my memory of how to do things in java. Problem at hand is, I am unable to get the color chooser to come up when I click on the jmenuitem clr (which is font color) the following code show's what I have so far:
Color Chooser Class:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.colorchooser.*;
/* ColorChooserDemo.java requires no other files. */
#SuppressWarnings("serial")
public class ColorChooserDemo extends JPanel
implements ChangeListener {
protected JColorChooser tcc;
protected JLabel banner;
public ColorChooserDemo() {
super(new BorderLayout());
//Set up color chooser for setting text color
tcc = new JColorChooser();
tcc.getSelectionModel().addChangeListener(this);
tcc.setBorder(BorderFactory.createTitledBorder(
"Choose Text Color"));
add(tcc, BorderLayout.PAGE_END);
}
public void stateChanged(ChangeEvent e) {
Color newColor = tcc.getColor();
FirstWindow.ta1.setForeground(newColor);
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("ColorChooserDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
JComponent newContentPane = new ColorChooserDemo();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Main Class:
import java.awt.EventQueue;
public class Main{
protected static Object fw;
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable(){
#Override
public void run() {
// TODO Auto-generated method stub
try
{
FirstWindow fw = new FirstWindow();
fw.setVisible(true);
} catch (Exception e)
{
e.printStackTrace();
}
}
});
}
}
FirstWindow class:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
public class FirstWindow extends JFrame {
private static final long serialVersionUID = 1L;
protected JColorChooser tcc;
protected static JTextArea ta1;
public FirstWindow() {
super("Note Pad");
Font font = new Font("Verdana", Font.BOLD, 12);
//Setting the size of the note pad
setSize(650, 745);
setDefaultCloseOperation(EXIT_ON_CLOSE);
//Create the MenuBar
JMenuBar mb = new JMenuBar();
setJMenuBar(mb);
//Create the panel to hold everything in
JPanel p = new JPanel();
//Create the Text Area
final JTextArea ta1 = new JTextArea();
ta1.setFont(font);
ta1.setMargin(new Insets(5,5,5,5));
ta1.setLineWrap(true);
ta1.setWrapStyleWord(true);
//Create the Scroll Pane to hold the Text Area
final JScrollPane sp = new JScrollPane(ta1);
sp.setPreferredSize(new Dimension(625,675));
sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
//Create the menu's
JMenu format = new JMenu("Format");
//Create menu item for picking font color
JMenuItem clr = new JMenuItem("Font Color");
clr.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
ColorChooserDemo ccd = new ColorChooserDemo();
ccd.setVisible(true);
}
});
//adding the menu items to the file menu tab
//adding menu items to the edit tab
//adding menu items to the format tab
format.add(clr);
//adding the menus to the menu bar
mb.add(format);
//adding the scroll pane to the panel
p.add(sp);
add(p, BorderLayout.CENTER);
}
}
Probably the easiest way to show the ColorChooser is the following:
In the ColorChooserDemo class, you have the method private static void createAndShowGUI(), which you should declare public.
Then, replace the ActionListener for the menu item to the following:
clr.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
ColorChooserDemo.createAndShowGUI();
}
});
Your ColorChooserDemo class extends JPanel, not JFrame. You first need a JFrame, then add the panel, then show the JFrame. This is what happens in the createAndShowGUI() method.
Edit:
I understood that you only wanted to know how to show the ColorChooserDemo when selecting a menu item.
However, to actually set the color, you might want to skip using your own ColorChooserDemo class, and replace the ActionListener code with the following:
clr.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
Color c = JColorChooser.showDialog(ta1, "ColorChooserDemo", null);
ta1.setForeground(c);
}
});
An SSCE is easier not only for us to provide a solution, as Andrew suggested, but it may also help you figure out and understand what to do. Anyway, here's a quick example of opening a colour chooser after pressing a JMenuItem:
item.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JColorChooser jColorChooser = new JColorChooser();
JDialog jDialog = new JDialog();
jDialog.setContentPane(jColorChooser);
jDialog.pack();
jDialog.setVisible(true);
}
});
LE: (sorry, new to colour choosers myself) or just use JColorChooser.showDialog()

JFrame's getFocusOwner() not being helpful

I am working with a Swing program and having a little trouble. The program has two windows (both are JFrames). The main window is just fine and should not be relevant to this issue.
The window I am having issues with contains a JScrollPane with a JPanel in it, and has a JMenuBar. The JPanel has a bunch of JTextComponents (some JTextFields, some JTextAreas) on it.
What I want to do is have an ActionListener attached to a JMenuItem find the JTextComponent that has focus.
I have seen the previous posts at focused component reference and How to find out which object currently has focus. My issue is that calling the particular window's getFocusOwner() method merely returns the JFrame's JRootPane, which is utterly unhelpful. Both the JScrollPane and the JPanel in question are focusable according to their isFocusable() methods. This happens even if I actually enter text into one of the JTextComponents before clicking the menu item. The cursor still blinks in the text field while I open the menu, and everything. For what it's worth, getMostRecentFocusOwner() also simply returns the JRootPane.
If you use TextActions, the action knows which JTextComponent has the focus. I've modified some code that I found here to show that even if the TextActions come from one JTextArea, they still will automatically work on any and all text components that have focus:
import java.awt.GridLayout;
import javax.swing.*;
public class TextActionExample {
public static void main(String[] args) {
// Create a text area.
JTextArea ta = new JTextArea(15, 30);
ta.setLineWrap(true);
// Add all actions to the menu (split into two menus to make it more
// usable).
Action[] actions = ta.getActions();
JMenuBar menubar = new JMenuBar();
JMenu actionmenu = new JMenu("Actions");
menubar.add(actionmenu);
JMenu firstHalf = new JMenu("1st Half");
JMenu secondHalf = new JMenu("2nd Half");
actionmenu.add(firstHalf);
actionmenu.add(secondHalf);
int mid = actions.length / 2;
for (int i = 0; i < mid; i++) {
firstHalf.add(actions[i]);
}
for (int i = mid; i < actions.length; i++) {
secondHalf.add(actions[i]);
}
JTextField textField = new JTextField(20);
JPanel textFieldPanel = new JPanel();
textFieldPanel.add(textField);
JPanel mainPanel = new JPanel(new GridLayout(1, 0, 5, 5));
mainPanel.add(new JScrollPane(ta));
mainPanel.add(new JScrollPane(new JTextArea(15, 30)));
mainPanel.add(textFieldPanel);
// Show it . . .
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(mainPanel);
f.setJMenuBar(menubar);
f.pack();
f.setVisible(true);
}
}
This is very interesting stuff that I have to learn more about.
I think I have solved this, because of the fact that you lose focus when you click on a menu item, we simply have to wait for focus to return to the component before we check who has focus, I have done this using a swing timer that waits 100ms and then executes its method to check which component has focus:
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.TimerTask;
import javax.swing.*;
public class JavaApplication180 extends JFrame {
private JTextField[] JTextFields;
private JMenuBar menuBar;
private JMenu menu;
private JMenuItem item;
public JavaApplication180() {
initComponents();
createAndShowUI();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new JavaApplication180();
}
});
}
private void createAndShowUI() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(new GridLayout(2, 2, 10, 10));
setJMenuBar(menuBar);
addComponentsToPane();
pack();
setVisible(true);
}
private void initComponents() {
JTextFields = new JTextField[4];
menuBar = new JMenuBar();
item = new JMenuItem("Who has focus?");
item.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
TimerTask tt = new TimerTask() {
#Override
public void run() {
JOptionPane.showMessageDialog(null, getMostRecentFocusOwner().getName());
}
};
new java.util.Timer().schedule(tt, 100);
}
});
menu = new JMenu("File");
menu.add(item);
menuBar.add(menu);
}
private void addComponentsToPane() {
for (int i = 0; i < JTextFields.length; i++) {
JTextFields[i] = new JTextField();
JTextFields[i].setText(String.valueOf(i));
JTextFields[i].setName(String.valueOf(i));
getContentPane().add(JTextFields[i]);
}
}
}
I'm probably too late, but I just did the following in my JFrame constructor.
this.rootPane.setFocusable(false);
Now
getFocusOwner()
will return the current JTextComponent instead of the rootPane.
I then used this code in an ActionListener attached to my JMenuItem to select the text within it.
if (getFocusOwner() instanceof JTextField)
{
((JTextField) getMostRecentFocusOwner()).selectAll();
}
It should be noted that If you have a JScrollPane etc, you may have to use setFocusable(false) on all the components between the rootPane and the textfields.
Hope this helps anyone else with the same issue!
Source: Personal Experience
When I've needed this, I wrote a focus listener. I had a JPanel with two columns of JTextFields and the focus listener kept track of which column was last used by the user. I enablesd the user to enter some text into that last focused column with a button click. You would use just one instance of your FocusListener for all text fields and have a field referencing the most recently focused component. Your menu action can then query that field to determine which text field to use.
See http://docs.oracle.com/javase/tutorial/uiswing/events/focuslistener.html

Can't Add JMenuItem to JMenu in JPopupMenu

I've got a new UI I'm working on implementing in Java and I'm having trouble implementing a JPopupMenu containing a JMenu (as well as several JMenuItems), which itself contains several JMenuItems. The JPopupMenu appears where I click the RMB, and it looks good, but the "Connect" JMenu doesn't seem to have any children when I mouse-over, despite my best efforts to .add() them.
Having looked at several examples online, I haven't seen any that specifically implement a listener for mouseEntered() to roll out the sub-items. I'm of a mind that I'm messing something up in my menu initialization method.
I've attached the pertinent code for your perusal.
//Elsewhere...
private JPopupMenu _clickMenu;
//End Elsehwere...
private void initializeMenu()
{
_clickMenu = new JPopupMenu();
_clickMenu.setVisible(false);
_clickMenu.add(generateConnectionMenu());
JMenuItem menuItem;
menuItem = new JMenuItem("Configure");
addMenuItemListeners(menuItem);
_clickMenu.add(menuItem);
menuItem = new JMenuItem("Status");
addMenuItemListeners(menuItem);
_clickMenu.add(menuItem);
}
private JMenu generateConnectionMenu()
{
JMenu menu = new JMenu("Connect");
List<Port> portList = _database.getAllPortsInCard(_cardId);
for(int i = 0; i < portList.size(); i++)
{
menu.add(new JMenuItem(portList.get(i).getName()));
}
return menu;
}
The code is certainly not the prettiest, but go easy on me as it's been altered too many times today as time permitted while I tried to figure out why this wasn't working. I'm thinking it may be a question of scope, but I've tried a few different code configurations to no avail. Feel free to ask any followup questions or smack me for an obvious oversight (it's happened before...). Thanks all!
Edit:
Chalk this one up to a lack of experience with Java and Swing... I was manually positioning and making the JPopupMenu visible instead of using the JComponent.setComponentPopupMenu(menu) method. After doing this for the card module in the above image (itself a JButton), the submenu displays correctly. A different, functional version of the initialization code is included below.
private void initializeMenu()
{
_cardMenu = new JPopupMenu();
JMenu menu = new JMenu("Connect");
JMenuItem menuItem;
menuItem = new JMenuItem("1");
menu.add(menuItem);
menuItem = new JMenuItem("2");
menu.add(menuItem);
_cardMenu.add(menu);
_cardMenu.add(new JMenuItem("Configure"));
_cardMenu.add(new JMenuItem("Status"));
_mainButton.setComponentPopupMenu(_cardMenu); //Important, apparently!
}
So, lesson learned. Thanks for the help guys!
This is common Bug or Swing property that in one moment can be visible only one Lightweight popup window, same issue is e.g. with popup from JComboBox added into JPopupMenu,
change Lightweight property to the Heavyweight
better would be
use un_decorated JDialog or JOptionPane with JComponents
EDIT #trashgod
everything works as I excepted, all JMenus, JMenuItems are visible and repeatly fired correct evets
code
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class ContextMenu implements ActionListener, MenuListener, MenuKeyListener {
private JTextArea textArea = new JTextArea();
public ContextMenu() {
final JPopupMenu contextMenu = new JPopupMenu("Edit");
JMenu menu = new JMenu("Sub Menu");
menu.add(makeMenuItem("Sub Menu Save"));
menu.add(makeMenuItem("Sub Menu Save As"));
menu.add(makeMenuItem("Sub Menu Close"));
menu.addMenuListener(this);
JMenu menu1 = new JMenu("Sub Menu");
menu1.add(makeMenuItem("Deepest Sub Menu Save"));
menu1.add(makeMenuItem("Deepest Sub Menu Save As"));
menu1.add(makeMenuItem("Deepest Sub Menu Close"));
menu.add(menu1);
menu1.addMenuListener(this);
contextMenu.add(menu);
contextMenu.add(makeMenuItem("Plain Save"));
contextMenu.add(makeMenuItem("Plain Save As"));
contextMenu.add(makeMenuItem("Plain Close"));
contextMenu.addMenuKeyListener(this);
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
frame.add(panel);
panel.setComponentPopupMenu(contextMenu);
textArea.setInheritsPopupMenu(true);
panel.add(BorderLayout.CENTER, textArea);
JTextField textField = new JTextField();
textField.setInheritsPopupMenu(true);
panel.add(BorderLayout.SOUTH, textField);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 200);
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
textArea.append(e.getActionCommand() + "\n");
}
private JMenuItem makeMenuItem(String label) {
JMenuItem item = new JMenuItem(label);
item.addActionListener(this);
return item;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
ContextMenu contextMenu = new ContextMenu();
}
});
}
public void menuSelected(MenuEvent e) {
textArea.append("menuSelected" + "\n");
}
public void menuDeselected(MenuEvent e) {
textArea.append("menuDeselected" + "\n");
}
public void menuCanceled(MenuEvent e) {
textArea.append("menuCanceled" + "\n");
}
public void menuKeyTyped(MenuKeyEvent e) {
textArea.append("menuKeyTyped" + "\n");
}
public void menuKeyPressed(MenuKeyEvent e) {
textArea.append("menuKeyPressed" + "\n");
}
public void menuKeyReleased(MenuKeyEvent e) {
textArea.append("menuKeyReleased" + "\n");
}
}
I don't see an obvious problem in the code shown, although #mKorbel's point may apply. For reference, this ControlPanel adds a subMenu with several items.

Categories