i am working on a word processor and my hope is to allow the user do what all word processors allow them to do. My issue at the moment is trying to understand how to force text that is being wrote by the user on to the next line once the maximum width has been reached (the size of the frame). For example if i am writing a sentence (or question on stack overflow) once my text hits the boundary of the text area it automatically brings me to the next line without me pressing Enter/return. After doing some research into line wrapping i came across the following
http://www.java-forums.org/awt-swing/59790-line-wrapping-jtextpane.html
Toggling text wrap in a JTextpane
however i cannot seem to get the behavior i want from the JTextPane below is my code, as always i appreciate any assistance offered.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
public class WordFrame{
private JFrame appFrame;
private JMenuBar menuBar;
private JMenu fileMenu, editMenu, viewMenu;
JMenuItem saveMenuItem, openMenuItem, newMenuItem, exitMenuItem, fontMenuItem;
JTextPane textArea = new JTextPane();
static final int WIDTH = 1280, HEIGHT = 980;
private JScrollPane scrollBar = new JScrollPane(textArea);
JPanel wordPanel = new JPanel();
JFileChooser fileChooser = new JFileChooser();
private int textHeight = 12;
private Font defaultFont = new Font(Font.SANS_SERIF, 2, textHeight);
public WordFrame(){
appFrame = new JFrame();
setUI();
addMenuBar();
textArea.setFont(defaultFont);
}
public JFrame getAppFrame(){
return appFrame;
}
public void setFrameVisibility(boolean isVisible){
if(isVisible == true){
appFrame.setVisible(true);
}
else{
appFrame.setVisible(false);
}
}
public void setUI(){
appFrame.setTitle("Word Processor");
appFrame.setIconImage(new ImageIcon(this.getClass().getResource("Bridge.jpg")).getImage());
appFrame.setSize(WIDTH, HEIGHT);
appFrame.setLocation(0,0);
appFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
scrollBar.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
// scrollbar.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
wordPanel.setLayout(new BorderLayout());
appFrame.add(wordPanel);
textArea.setPreferredSize(new Dimension(400,500));
appFrame.add(scrollBar);
wordPanel.add(textArea);
scrollBar.setViewportView(wordPanel);
}
public void addMenuBar(){
menuBar = new JMenuBar();
fileMenu = new JMenu(" File ");
editMenu = new JMenu("Edit ");
viewMenu = new JMenu("View ");
newMenuItem = new JMenuItem("New");
fileMenu.add(newMenuItem);
fileMenu.addSeparator();
fileMenu.setMnemonic('f');
openMenuItem = new JMenuItem("Open");
fileMenu.add(openMenuItem);
saveMenuItem = new JMenuItem("Save");
fileMenu.add(saveMenuItem);
fileMenu.addSeparator();
exitMenuItem = new JMenuItem("Exit");
fileMenu.add(exitMenuItem);
fontMenuItem = new JMenuItem("Font");
editMenu.add(fontMenuItem);
menuBar.add(fileMenu);
menuBar.add(editMenu);
menuBar.add(viewMenu);
appFrame.setJMenuBar(menuBar);
}
public void setFontSize(int i){
this.textHeight = i;
}
public void addListener(ActionListener listener){
openMenuItem.addActionListener(listener);
exitMenuItem.addActionListener(listener);
saveMenuItem.addActionListener(listener);
}
}
After inserting code that i found on the internet. The text wraps once the edge (right) is hit by the text (basically if it goes to the max right of the application screen it automatically drops down to a new line. However a new issue has occurred this involves the JScrollBar, as everyone would expect, once text hits the bottom of the application screen a scrollbar would update to offer the user the ability to scroll up and down the page, this would make sense, however my code doesn't allow this. Here is the ammended code after my attempt to fix the line wrap issue (i still consider this the same question), further more if the following is commented out, text wrapping no longer works
textArea.setPreferredSize(new Dimension(400,500));
the code up there causes text wrap to fail completely.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
public class WordFrame{
private JFrame appFrame;
private JMenuBar menuBar;
private JMenu fileMenu, editMenu, viewMenu;
JMenuItem saveMenuItem, openMenuItem, newMenuItem, exitMenuItem, fontMenuItem;
JTextPane textArea = new JTextPane();
static final int WIDTH = 1280, HEIGHT = 980;
private JScrollPane scrollBar = new JScrollPane(textArea);
JPanel wordPanel = new JPanel();
JFileChooser fileChooser = new JFileChooser();
private int textHeight = 12;
private Font defaultFont = new Font(Font.SANS_SERIF, 2, textHeight);
public WordFrame(){
appFrame = new JFrame();
setUI();
addMenuBar();
textArea.setFont(defaultFont);
}
public JFrame getAppFrame(){
return appFrame;
}
public void setFrameVisibility(boolean isVisible){
if(isVisible == true){
appFrame.setVisible(true);
}
else{
appFrame.setVisible(false);
}
}
public void setUI(){
appFrame.setTitle("Word Processor");
appFrame.setIconImage(new ImageIcon(this.getClass().getResource("Bridge.jpg")).getImage());
appFrame.setSize(WIDTH, HEIGHT);
appFrame.setLocation(0,0);
appFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
scrollBar.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollBar.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
wordPanel.setLayout(new BorderLayout());
// appFrame.getContentPane().add(scrollBar, BorderLayout.CENTER);
textArea.setPreferredSize(new Dimension(400,500));
appFrame.add(wordPanel);
appFrame.add(scrollBar);
wordPanel.add(textArea);
// appFrame.add(textArea);
scrollBar.setViewportView(wordPanel);
textArea.setEditorKit(new WrapEditorKit());
}
public void addMenuBar(){
menuBar = new JMenuBar();
fileMenu = new JMenu(" File ");
editMenu = new JMenu("Edit ");
viewMenu = new JMenu("View ");
newMenuItem = new JMenuItem("New");
fileMenu.add(newMenuItem);
fileMenu.addSeparator();
fileMenu.setMnemonic('f');
openMenuItem = new JMenuItem("Open");
fileMenu.add(openMenuItem);
saveMenuItem = new JMenuItem("Save");
fileMenu.add(saveMenuItem);
fileMenu.addSeparator();
exitMenuItem = new JMenuItem("Exit");
fileMenu.add(exitMenuItem);
fontMenuItem = new JMenuItem("Font");
editMenu.add(fontMenuItem);
menuBar.add(fileMenu);
menuBar.add(editMenu);
menuBar.add(viewMenu);
appFrame.setJMenuBar(menuBar);
}
public void setFontSize(int i){
this.textHeight = i;
}
public void addListener(ActionListener listener){
openMenuItem.addActionListener(listener);
exitMenuItem.addActionListener(listener);
saveMenuItem.addActionListener(listener);
fontMenuItem.addActionListener(listener);
}
class WrapEditorKit extends StyledEditorKit {
ViewFactory defaultFactory=new WrapColumnFactory();
public ViewFactory getViewFactory() {
return defaultFactory;
}
}
class WrapColumnFactory implements ViewFactory {
public View create(Element elem) {
String kind = elem.getName();
if (kind != null) {
if (kind.equals(AbstractDocument.ContentElementName)) {
return new WrapLabelView(elem);
} else if (kind.equals(AbstractDocument.ParagraphElementName)) {
return new ParagraphView(elem);
} else if (kind.equals(AbstractDocument.SectionElementName)) {
return new BoxView(elem, View.Y_AXIS);
} else if (kind.equals(StyleConstants.ComponentElementName)) {
return new ComponentView(elem);
} else if (kind.equals(StyleConstants.IconElementName)) {
return new IconView(elem);
}
}
// default to text display
return new LabelView(elem);
}
}
class WrapLabelView extends LabelView {
public WrapLabelView(Element elem) {
super(elem);
}
public float getMinimumSpan(int axis) {
switch (axis) {
case View.X_AXIS:
return 0;
case View.Y_AXIS:
return super.getMinimumSpan(axis);
default:
throw new IllegalArgumentException("Invalid axis: " + axis);
}
}
}
}
Related
When I add JFileChooser and initialize it, then it throws the NullPointerException. Without JFileChooser, the same code runs pretty well every time I compile and run. But when I add JFileChooser then it throws the Exception. Sometimes, it runs successfully and sometimes it doesn't.Exceptionis:
Exception in thread "main" java.lang.NullPointerException
at javax.swing.text.PlainView.getPreferredSpan(PlainView.java:233)
at javax.swing.plaf.basic.BasicTextUI$RootView.getPreferredSpan(BasicTextUI.java:1353)
at javax.swing.plaf.basic.BasicTextUI.getPreferredSize(BasicTextUI.java:921)
at javax.swing.plaf.basic.BasicTextAreaUI.getPreferredSize(BasicTextAreaUI.java:120)
at javax.swing.JComponent.getPreferredSize(JComponent.java:1659)
at javax.swing.JTextArea.getPreferredSize(JTextArea.java:619)
at javax.swing.ScrollPaneLayout.layoutContainer(ScrollPaneLayout.java:791)
at java.awt.Container.layout(Container.java:1508)
at java.awt.Container.doLayout(Container.java:1497)
at java.awt.Container.validateTree(Container.java:1693)
at java.awt.Container.validateTree(Container.java:1702)
at java.awt.Container.validateTree(Container.java:1702)
at java.awt.Container.validateTree(Container.java:1702)
at java.awt.Container.validateTree(Container.java:1702)
at java.awt.Container.validate(Container.java:1628)
at java.awt.Container.validateUnconditionally(Container.java:1665)
at java.awt.Window.show(Window.java:1033)
at java.awt.Component.show(Component.java:1654)
at java.awt.Component.setVisible(Component.java:1606)
at java.awt.Window.setVisible(Window.java:1014)
at notepad.Notepad.<init>(Notepad.java:66)
at notepad.Notepad.main(Notepad.java:144)
My code is:
package notepad;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class Notepad extends JFrame implements ActionListener{
private JTextArea area;
private ImageIcon frameicon;
private JMenu filemenu;
private JMenu editmenu;
private JMenu formatmenu;
private JMenu helpmenu;
private JScrollPane scroll;
private Font font;
private JMenuBar menubar;
private JMenuItem newmenuitem;
private JMenuItem openmenuitem;
private JMenuItem savemenuitem;
private JMenuItem exitmenuitem;
private int msg;
private int returnVal;
private JFileChooser choose;
public Notepad(){
initComponents();
setComponents();
setTitle("Simple Notepad");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocation(500, 100);
setResizable(true);
setSize(600,600);
setJMenuBar(menubar);
menubar.add(filemenu);
menubar.add(editmenu);
menubar.add(formatmenu);
menubar.add(helpmenu);
filemenu.add(newmenuitem);
filemenu.add(openmenuitem);
filemenu.add(savemenuitem);
filemenu.add(exitmenuitem);
add(scroll);
setIconImage(frameicon.getImage());
setVisible(true);
}
public final void initComponents(){
area = new JTextArea();
scroll = new JScrollPane (area, //no need of add textArea when added in JScrollPane
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
menubar = new JMenuBar();
filemenu = new JMenu(" File");
editmenu = new JMenu(" Edit");
formatmenu = new JMenu(" Format");
helpmenu = new JMenu(" Help");
newmenuitem = new JMenuItem(" New");
openmenuitem = new JMenuItem(" Open");
savemenuitem = new JMenuItem(" Save");
exitmenuitem = new JMenuItem(" Exit");
choose = new JFileChooser("E:");
font = new Font("Calibri",Font.PLAIN,26);
frameicon = new ImageIcon(getClass().getResource("/res/setting.png"));
}
public final void setComponents(){
area.setSize(600,600);
area.setBackground(Color.WHITE);
area.setFont(font);
//adding ActionListener
newmenuitem.addActionListener(this);
exitmenuitem.addActionListener(this);
openmenuitem.addActionListener(this);
}
#Override
public void actionPerformed(ActionEvent e){
//if newmenuitemclicked
if(e.getSource()==newmenuitem) {
if(area.getText()!=""){
msg = JOptionPane.showConfirmDialog(menubar, "DO you want to save changes?");
if(msg == JOptionPane.YES_OPTION){
try {
FileOutputStream file = new FileOutputStream("E:\\newdocument.txt");
String s = area.getText();
byte c[] = s.getBytes();
file.write(c);
area.setText("");
JOptionPane.showMessageDialog(menubar, "File saved as E:\\newdocument.txt");
file.close();
} catch (FileNotFoundException ex) {
} catch (IOException ex) {
}
}
if(msg == JOptionPane.NO_OPTION){
}
}
}
if(e.getSource() == exitmenuitem){
msg = JOptionPane.showConfirmDialog(menubar, "Are you sure you want to exit?");
if(msg == JOptionPane.YES_OPTION)
System.exit(0);
}
if(e.getSource() == openmenuitem){
}
}
public static void main(String[] args) {
Notepad n = new Notepad();
}
}
No relevance to JFileChooser I think. Seems one of your components is not instantiated properly.
at java.awt.Window.setVisible(Window.java:1014)
And you can't call its setVisible(true) method.
Anyway to realize the true cause you should include your code.
Update: since your code is included, you can't use setVisible method in constructor. Use it in init() method.
It's because your object won't get instanced properly before constructor execution ends.
I've tried different methods to fix this, but apparently nothing works. Because I am new to java I actually don't know if there's something wrong with my code.
I've tried setting the size of the text area that is supposed to go into the SOUTH part of the border layout, but the size is still to small to see.
Anyone know of a solution?
package package1;
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class SimpleDatabasePanel extends JFrame implements ActionListener {
private JMenuBar menuBar;
private JMenu file;
private JMenuItem save, load, quit;
private JButton add, undo, find, delete, display;
private JScrollPane pane;
private JTable table;
private JPanel panel;
private JTextArea tName, tGNum, tGPA, results;
private JLabel name, gNum, gpa;
private LinkedList list;
public SimpleDatabasePanel(){
setLayout(new BorderLayout());
setTitle("Simple Database");
//setSize(1000,1000);
menuBar = new JMenuBar();
setJMenuBar(menuBar);
file = new JMenu("File");
quit = new JMenuItem("Quit");
save = new JMenuItem("Save");
load = new JMenuItem("Load");
add = new JButton("Add");
undo = new JButton("Undo");
find = new JButton("Find");
delete = new JButton("Delete");
display = new JButton("Display");
tName = new JTextArea();
tGNum = new JTextArea();
tGPA = new JTextArea();
results = new JTextArea(10,20);
name = new JLabel("Name");
gNum = new JLabel("G Number");
gpa = new JLabel("GPA");
list = new LinkedList();
panel = new JPanel();
panel.setLayout(new GridLayout(3, 4, 4, 4));
//frame = new JFrame();
pane = new JScrollPane();
pane.setSize(300, 60);
table = new JTable();
menuBar = new JMenuBar();
menuBar.add(file);
file.add(save);
file.add(load);
file.add(quit);
panel.add(name);
panel.add(tName);
panel.add(undo);
panel.add(add);
panel.add(gNum);
panel.add(tGNum);
panel.add(find);
panel.add(delete);
panel.add(gpa);
panel.add(tGPA);
panel.add(display);
pane.add(results);
add(menuBar, BorderLayout.NORTH);
add(panel, BorderLayout.CENTER);
add(pane, BorderLayout.SOUTH);
this.pack();
ButtonListener listener = new ButtonListener();
file.addActionListener(file.getAction());
find.addActionListener(listener);
undo.addActionListener(listener);
save.addActionListener(this);
quit.addActionListener(this);
add.addActionListener(listener);
load.addActionListener(this);
delete.addActionListener(listener);
display.addActionListener(listener);
}
public void actionPerformed(ActionEvent e) {
JMenuItem file = (JMenuItem) e.getSource();
if(file == quit){
System.exit(0);
}
if(file == load){
String filename = JOptionPane.showInputDialog("Enter File Name: ");
(list).load(filename);
}
if(file == save){
String filename = JOptionPane.showInputDialog("Enter File Name: ");
(list).save(filename);
}
}
private class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
if(event.getSource() == add){
}
if(event.getSource() == delete){
}
if(event.getSource() == display){
}
if(event.getSource() == find){
}
if(event.getSource() == undo){
}
}
}
public static void main(String[] args){
SimpleDatabasePanel s =new SimpleDatabasePanel();
s.setVisible(true);
s.setResizable(false);
}
}
change this
pane.add(results);
to this
pane.setViewportView(results);
or this
pane.getViewport().add(results, null);
use setViewportView or getViewport().add to set component to jscrollpane.also you can pass component (jtextarea ) to constructor of jscrollpane.read more about jscrollpane here
output
I am using the menu to try to change the button number.
But this should not refresh.
How do I solve this?
I want 'file -> modify -> button 10x10 -> 20x20 change. '
To test and modify the source below. Please...
Please give me change the source. TT
package com.test;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class MineMain extends JFrame {
private GridLayout grid;
private JPanel jp;
private int rownum, colnum;
private JButton[][] btn = null;
public MineMain(){
super("MINE");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Menu_Init();
// grid = new GridLayout();
// jp = new JPanel();
rownum = 10;
colnum = 10;
Init(200, 250);
}
private void setBtn(int row, int col){
btn = new JButton[row][col];
}
public void Init(int w, int h){
if(jp != null)
jp.removeAll();
else
jp = null;
btn = null;
jp = null;
// jp.removeAll();
grid = new GridLayout(rownum, colnum, 0, 0);
jp = new JPanel(grid);
setBtn(rownum, colnum);
for(int i=0;i<btn.length;i++){
for(int j=0;j<btn[i].length;j++){
btn[i][j] = new JButton();
jp.add(btn[i][j]);
}
}
// jp.revalidate();
// jp.repaint();
this.add(jp);
this.setSize(w, h);
this.setLocation(200, 200);
this.setVisible(true);
this.setResizable(false);
}
public void Menu_Init(){
JMenuBar bar = new JMenuBar();
setJMenuBar(bar);
JMenu filemenu = new JMenu("File(F)");
filemenu.setMnemonic('F');
JMenuItem startmenu = new JMenuItem("New Game(N)");
startmenu.setMnemonic('N');
startmenu.setActionCommand("NEW START");
startmenu.addActionListener(new MenuActionListener());
filemenu.add(startmenu);
JMenuItem minecntmenu = new JMenuItem("MINE MODIFY(M)");
minecntmenu.setMnemonic('M');
minecntmenu.setActionCommand("MODIFY");
minecntmenu.addActionListener(new MenuActionListener());
filemenu.add(minecntmenu);
JMenuItem close = new JMenuItem("CLOSE(C)");
close.setMnemonic('C');
filemenu.add(close);
bar.add(filemenu); //JMenuBar에 JMenu 부착
}
private class MenuActionListener implements ActionListener {
public void actionPerformed(ActionEvent e){
if(e.getActionCommand().equals("START")){
JOptionPane.showMessageDialog(null, "NEW GAME", "MINE", JOptionPane.YES_NO_OPTION);
} else if(e.getActionCommand().equals("MODIFY")){
modify(2);
}
}
}
private void modify(int lvl){
rownum = 20;
colnum = 20;
Init(400, 500);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new MineMain();
}
}
I see you are calling Init() again on modify().
Within Init(), I am assuming you are using
if(jp != null)
jp.removeAll();
else
jp = null;
to clear out the JPanel?
You want to remove the existing JPanel (i.e. jp) from the JFrame (i.e. this) before continuing at this point.
So, you could change your code to
if(jp != null) {
// JPanel already exists. so, remove JPanel jp from the JFrame
this.remove(jp);
jp.removeAll();
} else
jp = null;
I want to put a rollover effect in my JMenu this is my code:
Icon firstPicAcc= new ImageIcon(Welcome.class.getResource("/app/resources/user1.jpg"));
Icon secPicAcc= new ImageIcon(Welcome.class.getResource("/app/resources/user2.jpg"));
JMenu mnAccountSettings = new JMenu("Account Settings");
mnAccountSettings.addMouseWheelListener(new MouseWheelListener() {
public void mouseWheelMoved(MouseWheelEvent arg0) {
}
});
mnAccountSettings.setFont(new Font("Dialog", Font.PLAIN, 20));
mnAccountSettings.setForeground(new Color(0, 153, 0));
mnAccountSettings.setBackground(new Color(255, 204, 255));
mnAccountSettings.setRolloverEnabled(true);
mnAccountSettings.setIcon(firstPicAcc);
mnAccountSettings.setRolloverIcon(secPicAcc);
mnAccount.add(mnAccountSettings);
how can i do that? thanks!
What should happen is when I rolled my mouse over the JMenu bar the original icon should change into another icon.
What you want to do is add a ChangeListener to the JMenuItem and check if it's selected or armed and change the icon accordingly. The ChangeListener works for both keyboard and mouse.
See this good read by #kleopatra
private JMenuItem createMenuItem(final ImageIcon icon, String title) {
JMenuItem item = new JMenuItem(title);
item.setIcon(icon);
ChangeListener cl = new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
if (e.getSource() instanceof JMenuItem) {
JMenuItem item = (JMenuItem) e.getSource();
if (item.isSelected() || item.isArmed()) {
item.setIcon(stackIcon);
} else {
item.setIcon(icon);
}
}
}
};
item.addChangeListener(cl);
return item;
}
Here is running example. Just replace images with yours
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class RolloverMenuItem {
ImageIcon stackIcon = new ImageIcon(getClass().getResource("/resources/stackoverflow2.png"));
public RolloverMenuItem() {
ImageIcon newIcon = new ImageIcon(getClass().getResource("/resources/image/new.gif"));
ImageIcon saveIcon = new ImageIcon(getClass().getResource("/resources/image/open.gif"));
ImageIcon openIcon = new ImageIcon(getClass().getResource("/resources/image/save.gif"));
JMenu menu = new JMenu("File");
menu.setMnemonic(KeyEvent.VK_F);
JMenuItem item1 = createMenuItem(newIcon, "New");
JMenuItem item2 = createMenuItem(openIcon, "Open");
JMenuItem item3 = createMenuItem(saveIcon, "Save");
menu.add(item1);
menu.add(item2);
menu.add(item3);
JMenuBar menuBar = new JMenuBar();
menuBar.add(menu);
JFrame frame = new JFrame("Rollover MenuItem");
frame.setJMenuBar(menuBar);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 250);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JMenuItem createMenuItem(final ImageIcon icon, String title) {
JMenuItem item = new JMenuItem(title);
item.setIcon(icon);
ChangeListener cl = new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
if (e.getSource() instanceof JMenuItem) {
JMenuItem item = (JMenuItem) e.getSource();
if (item.isSelected() || item.isArmed()) {
item.setIcon(stackIcon);
} else {
item.setIcon(icon);
}
}
}
};
item.addChangeListener(cl);
return item;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new RolloverMenuItem();
}
});
}
}
I'm pretty new to programming, and I need to create a GUI for a pethouse program that allows the user to add, delete, and sort the records.
The problem is that for whatever reason my ActionListeners are not working. The GUI opens fine enough, but if I click on a menu item, nothing happens. The Quit MenuItem doesn't do anything, nor does the add animal do anything. The delete doesn't work either (though that may also be a programming error on my part.)
Here's the Code:
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.table.DefaultTableModel;
import scrap.knockoff;
public class knockoff extends JFrame {
private ButtonHandler handler;
static int animals;
static Color Backgroundcolor = Color.red;
private JTable thelist;
private JTextField search, breed, category, buyprice, sellprice;
private JMenuBar menuBar;
private JMenu menu;
private JMenuItem menuAdd, menuDelete, menuQuit;
private JLabel maintitle, breedquery, categoryquery, buypricequery, sellpricequery;
private JButton sortbreed, sortcat, sortdog, sortratios, searchButton, add, delete, modify;
private JPanel animalPane, sortPane, titlePane, searchPane, tablePane, optionPane;
static Container container;
static int recnumber;
static String control[] = new String[100];
static double buyprices, sellprices, profitratios;
static String BreedName, CategoryName;
static String Pets[][] = new String[50][5];
public knockoff() {
super("The Peel Pet House Program"); //This just changes the name at the top there.
setSize(700, 600);
Border paneEdge = BorderFactory.createEmptyBorder(0, 10, 10, 10);
JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.setLocation(0, 30);
tabbedPane.setSize(200, 100);
//These are our panels. The sortPane just keeps the buttons responsible for sorting the animals where they are. The animalPane is for the other functions (add, delete, whatnot) and the title pane
//just holds the title. The AnimalPane is just a constant, it's there just so that the Animals menu process has a place to be. The Table Pane holds the table.
tablePane = new JPanel();
tablePane.setLocation(200, 35);
tablePane.setSize(500, 500);
titlePane = new JPanel();
titlePane.setSize(700, 30);
animalPane = new JPanel();
Border greenline = BorderFactory.createLineBorder((Color.green).darker());
animalPane.setBorder(greenline);
animalPane.setLocation(0, 135);
animalPane.setSize(200, 400);
sortPane = new JPanel();
sortPane.setBorder(paneEdge);
search = new JTextField();
searchButton = new JButton("Search");
searchPane = new JPanel();
FlowLayout searchLayout = new FlowLayout();
searchPane.setLayout(searchLayout);
searchPane.setBorder(paneEdge);
search.setPreferredSize(new Dimension(190, 30));
searchPane.add(search);
searchPane.add(searchButton);
optionPane = new JPanel();
optionPane.setSize(100, 30);
//This establishes our table
String[] columns = {"Breed", "Category", "Buying Price", "Selling Price", "Profit Ratio"};
thelist = new JTable(Pets, columns);
JScrollPane listbrowser = new JScrollPane(thelist);
tablePane.add(listbrowser);
//These establish the buttons for our various sorting sprees.
sortbreed = new JButton("Breed");
sortcat = new JButton("Cat");
sortdog = new JButton("Dog");
sortratios = new JButton("Profit Ratio");
sortPane.add(sortbreed);
sortPane.add(sortcat);
sortPane.add(sortdog);
sortPane.add(sortratios);
//Our ever reliable menu bar maker.
menuBar = new JMenuBar();
setJMenuBar(menuBar);
menu = new JMenu("File");
menuBar.add(menu);
//The items of the file menu.
menuQuit = new JMenuItem("Quit");
menuQuit.addActionListener(handler);
menu.add(menuQuit);
//Animal Menu Creation
menu = new JMenu("Animals");
menuBar.add(menu);
menuAdd = new JMenuItem("Add an Animal");
menuAdd.addActionListener(handler);
menu.add(menuAdd);
menuDelete = new JMenuItem("Delete Animal");
menuDelete.addActionListener(handler);
menu.add(menuDelete);
//Adding everything to the container now.
Container container = getContentPane();
container.setLayout(null);
maintitle = new JLabel("The Piddly Penultimate Peel Pet House Program");
titlePane.add(maintitle);
container.setBackground(Backgroundcolor.darker()); //This just makes a darker version of red to set as the background on the Content Pane. Grey is boring.
container.add(tablePane);
container.add(titlePane);
container.add(tabbedPane);
container.add(animalPane);
container.add(optionPane);
tabbedPane.addTab("Sort By:", null, sortPane, "Sorts the Table");
tabbedPane.addTab("Search", null, searchPane, "The Search Function");
}
public static void main(String args[]) {
knockoff application = new knockoff();
application.setVisible(true);
}
private class ButtonHandler implements ActionListener {
public void actionPerformed(ActionEvent event) {
if (event.equals("Add an Animal")) {
addananimal();
} else if (event.equals("Delete Animal")) {
deleteanimal();
} else if (event.getSource().equals(add)) //getsource relates to the button, it just makes it so that anybody programming can freely change the text of the button without worrying about this.
{
addanimal();
} else if (event.getSource().equals(delete)) {
deleteanimal();
} else if (event.getSource().equals(sortbreed)) {
breedsort();
} else if (event.getSource().equals(sortcat)) {
} else if (event.getSource().equals(sortdog)) {
} else if (event.getSource().equals(sortratios)) {
} else if (event.equals("Quit")) {
hide();
System.exit(0);
}
}
//Add new Record Method
public void addananimal() {
container = getContentPane();
//Plate cleaner. Or dishwasher.
if (animalPane != null) {
container.remove(animalPane);
}
animalPane = new JPanel();
Border greenline = BorderFactory.createLineBorder((Color.green).darker());
animalPane.setBorder(greenline);
animalPane.setLocation(0, 135);
animalPane.setSize(200, 400);
FlowLayout animalLayout = new FlowLayout();
animalPane.setLayout(animalLayout);
breedquery = new JLabel("Add Animal Name:");
categoryquery = new JLabel("Cat or Dog?");
buypricequery = new JLabel("Buying Price:");
sellpricequery = new JLabel("Selling Price:");
animalPane.add(breedquery);
breed = new JTextField(18);
animalPane.add(breed);
animalPane.add(categoryquery);
category = new JTextField(18);
animalPane.add(category);
animalPane.add(buypricequery);
buyprice = new JTextField(18);
animalPane.add(buyprice);
animalPane.add(sellpricequery);
sellprice = new JTextField(18);
add = new JButton("Add Animal");
//The above list of .add and JComponent things were just to establish the
// contents of our new animalPane.
profitratios = Double.parseDouble(sellprice.getText()) / Double.parseDouble(buyprice.getText());
//This just makes finding the profit ratio an autonomous action.
add.addActionListener(handler);
animalPane.add(add);
container.add(animalPane);
setVisible(true);
}
public void addanimal() {
animals = animals + 1;
Pets[animals][0] = breed.getText();
Pets[animals][1] = category.getText();
Pets[animals][2] = buyprice.getText();
Pets[animals][3] = sellprice.getText();
Pets[animals][4] = profitratios + "";
breed.setText(" ");
category.setText(" ");
buyprice.setText(" ");
sellprice.setText(" ");
thelist.repaint(); //This is supposed to update the JTable in real time.
}
public void deleteanimal() {
removeSelectedRows(thelist);
}
public void removeSelectedRows(JTable table) {
DefaultTableModel model = (DefaultTableModel) table.getModel();
int[] rows = table.getSelectedRows();
for (int x = 0; x < rows.length; ++x) {
model.removeRow(rows[x] - x);
}
for (int x = 0; x < animals; ++x) {
if (Pets[x][0].equalsIgnoreCase(table.getValueAt(table.getSelectedRow(), 0) + "")) {
Pets[x][0] = null;
Pets[x][1] = null;
Pets[x][2] = null;
Pets[x][3] = null;
Pets[x][4] = null;
}
}
}
public void breedsort() {
for (int x = 0; x < animals; ++x) {
}
}
}
}
You never initialize the ButtonHandler, meaning that every time you call addActionListener(handler) you are essentially calling addActionListener(null)
Try initializing the handler in the constructor BEFORE you add it to anything...
public knockoff() {
super("The Peel Pet House Program"); //This just changes the name at the top there.
handler = new ButtonHandler();
Updated
Better yet, take a look at the Action API instead
You're not instantiating and regstering ButtonHandler anywhere...