Java EventHandler not working, why does it create new Frame? - java

I am trying to create an address book for a uni project and I am trying to get the GUI to be able to save the details that are input to the form to a file. Every time I click save on the GUI it creates a new Frame rather than executing the code that I have put in the even Handler. I am still fairly new to Java and I just can't see what is wrong with it.
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class AddressBook {
static AddressBookGui addressBookGui = new AddressBookGui();
static int writeCount;
File detailsFile = new File("customerDetails.txt");
public static void saveDetails() throws IOException {
String title = addressBookGui.txtTitle.getText();
FileWriter fw = new FileWriter("customerDetails.txt");
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter out = new PrintWriter(bw);
out.println(title);
out.close();
writeCount++;
}
}
Above is the Handler class, below is the GUI.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class AddressBookGui {
private JLabel lblTitle;
public JTextField txtTitle;
private JButton btnSaveDetails;
private JPanel panel;
private JFrame frame;
public static void main(String[] args) {
new AddressBookGui();
}
public AddressBookGui() {
createPanel();
addLabels();
addTextFields();
addButtons();
frame.add(panel);
frame.setVisible(true);
}
public void createPanel() {
frame = new JFrame();
frame.setTitle("Address Book");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800,950);
frame.setVisible(true);
panel = new JPanel();
panel.setLayout(null);
}
public void addLabels() {
lblTitle = new JLabel("Title");
lblTitle.setBounds(90,210,140,30);
panel.add(lblTitle);
}
public void addTextFields() {
txtTitle = new JTextField("");
txtTitle.setBounds(190,210,150,30);
panel.add(txtTitle);
}
public void addButtons() {
btnSaveDetails = new JButton("Save");
btnSaveDetails.setBounds(200,600,80,30);
btnSaveDetails.addActionListener(new SaveDetailsButton());
panel.add(btnSaveDetails);
}
public class SaveDetailsButton implements ActionListener {
public void actionPerformed(ActionEvent event) {
try {
AddressBook.saveDetails();
} catch (IOException e) {
JOptionPane.showMessageDialog(null, "File did not write correctly.", "Error", JOptionPane.ERROR_MESSAGE);
}
}
}
}
Thanks in advance.

Related

How do I add Command + Delete functionality in JTextPane [duplicate]

I have a small text editor that I made in Java Swing with JTextArea.
I want to implement the following:
When the user presses Command+Backspace I want to remove all the text from the beginning of the line up to the cursor. How to implement this? I tried using KeyListeners but it doesn't work.
For example (before user presses Command+Backspace) ...
Result (after user presses Command+Backspace) ...
My code (Not 100% exact compared to the image):
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class Main{
static JFrame frame = new JFrame();
static JTextArea textArea = new JTextArea();
static JScrollPane scrollPane = new JScrollPane(textArea);
public static void main(String[] args) throws BadLocationException {
frame.setTitle("Untitled");
addComponentsToFrame();
textArea.addKeyListener(new KeyListener(){
#Override
public void keyTyped(KeyEvent e) {
if(e.getKeyCode() == (Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx() | KeyEvent.VK_BACK_SPACE)){
System.out.println("Delete"); //Placeholder
}
}
#Override
public void keyPressed(KeyEvent e) {}
#Override
public void keyReleased(KeyEvent e) {}
});
}
public static void addComponentsToFrame(){
scrollPane.setAutoscrolls(true);
frame.add(scrollPane);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
For now when I have placed a print Statement as a place holder, since I don't know how to delete all the words from the beginning of the line up to the cursor (i.e. the logic).
Credits: #Abra
Solution:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.text.BadLocationException;
import java.awt.Toolkit;
public class TestSamplePrograms {
private JTextArea textarea;
private void buildAndShowGui() {
JFrame frame = new JFrame("Untitled");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createTextArea(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JScrollPane createTextArea() {
textarea = new JTextArea(20, 60);
InputMap im = textarea.getInputMap();
KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx());
im.put(ks, "del2EoL");
ActionMap am = textarea.getActionMap();
am.put("del2EoL", new Delete2EOL());
JScrollPane pane = new JScrollPane(textarea);
return pane;
}
#SuppressWarnings("serial")
private class Delete2EOL extends AbstractAction {
#Override
public void actionPerformed(ActionEvent e) {
int caretOffset = textarea.getCaretPosition();
int lineNumber = 0;
try {
lineNumber = textarea.getLineOfOffset(caretOffset);
int startOffset = textarea.getLineStartOffset(lineNumber);
int endOffset = textarea.getLineEndOffset(lineNumber);
textarea.replaceRange("", startOffset, endOffset);
} catch (BadLocationException ex) {
throw new RuntimeException(ex);
}
}
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> new TestSamplePrograms().buildAndShowGui());
}
}

Command + Backspace functionality in JTextArea

I have a small text editor that I made in Java Swing with JTextArea.
I want to implement the following:
When the user presses Command+Backspace I want to remove all the text from the beginning of the line up to the cursor. How to implement this? I tried using KeyListeners but it doesn't work.
For example (before user presses Command+Backspace) ...
Result (after user presses Command+Backspace) ...
My code (Not 100% exact compared to the image):
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class Main{
static JFrame frame = new JFrame();
static JTextArea textArea = new JTextArea();
static JScrollPane scrollPane = new JScrollPane(textArea);
public static void main(String[] args) throws BadLocationException {
frame.setTitle("Untitled");
addComponentsToFrame();
textArea.addKeyListener(new KeyListener(){
#Override
public void keyTyped(KeyEvent e) {
if(e.getKeyCode() == (Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx() | KeyEvent.VK_BACK_SPACE)){
System.out.println("Delete"); //Placeholder
}
}
#Override
public void keyPressed(KeyEvent e) {}
#Override
public void keyReleased(KeyEvent e) {}
});
}
public static void addComponentsToFrame(){
scrollPane.setAutoscrolls(true);
frame.add(scrollPane);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
For now when I have placed a print Statement as a place holder, since I don't know how to delete all the words from the beginning of the line up to the cursor (i.e. the logic).
Credits: #Abra
Solution:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.text.BadLocationException;
import java.awt.Toolkit;
public class TestSamplePrograms {
private JTextArea textarea;
private void buildAndShowGui() {
JFrame frame = new JFrame("Untitled");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createTextArea(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JScrollPane createTextArea() {
textarea = new JTextArea(20, 60);
InputMap im = textarea.getInputMap();
KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx());
im.put(ks, "del2EoL");
ActionMap am = textarea.getActionMap();
am.put("del2EoL", new Delete2EOL());
JScrollPane pane = new JScrollPane(textarea);
return pane;
}
#SuppressWarnings("serial")
private class Delete2EOL extends AbstractAction {
#Override
public void actionPerformed(ActionEvent e) {
int caretOffset = textarea.getCaretPosition();
int lineNumber = 0;
try {
lineNumber = textarea.getLineOfOffset(caretOffset);
int startOffset = textarea.getLineStartOffset(lineNumber);
int endOffset = textarea.getLineEndOffset(lineNumber);
textarea.replaceRange("", startOffset, endOffset);
} catch (BadLocationException ex) {
throw new RuntimeException(ex);
}
}
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> new TestSamplePrograms().buildAndShowGui());
}
}

Swing window not opening

I am creating a NotePad app in Java Swing but when I am trying to open a popup to set a title, it is not showing up.
The class that calls the popup:
import java.io.*;
import java.util.*;
import java.awt.event.*;
import javax.swing.*;
public class NewFile implements ActionListener{
public static String title;
public void actionPerformed(ActionEvent e){
PopupFileName popup = new PopupFileName();
/*try{
Thread.sleep(30000);
}catch (InterruptedException o){
o.printStackTrace();
}*/
JTextArea titl = popup.title;
title = titl.getText();
try{
File writer = new File(title+".txt");
if(writer.createNewFile()){
System.out.println("file created");
}else{
System.out.println("file exists");
}
}catch (IOException i) {
System.out.println("An error occurred.");
i.printStackTrace();
}
}
}
The popup class that is supposed to open:
import javax.swing.*;
public class PopupFileName{
static JFrame popup = new JFrame("File Title");
static JLabel titlel = new JLabel("Title:");
static public JTextArea title = new JTextArea();
public static void main(String[] args){
popup.setSize(200,300);
popup.setVisible(true);
popup.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
popup.add(titlel);
popup.add(title);
}
}
Is there any way I can make it visible and make it able to get the text before it is created?
Start by taking a look at:
Creating a GUI With Swing
How to Write an Action Listener
How to Use Scroll Panes
How to Use Buttons, Check Boxes, and Radio Buttons
How to Make Dialogs
You're running in an event driven environment, this means, something happens and then you respond to it.
The problem with your ActionListener is, it's trying to present a window and then, immediately, trying to get some result from it. The problem is, the window probably isn't even present on the screen yet.
What you need is some way to "stop" the code execution until after the user responds. This is where a modal dialog comes in.
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
JButton btn = new JButton("Test");
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String title = PopupFileName.getTitle(TestPane.this);
System.out.println(title);
}
});
add(btn);
}
}
public static class PopupFileName extends JPanel {
private JLabel titlel = new JLabel("Title:");
private JTextArea title = new JTextArea(20, 40);
public PopupFileName() {
setLayout(new BorderLayout());
add(titlel, BorderLayout.NORTH);
add(new JScrollPane(title));
}
public String getTitle() {
return title.getText();
}
public static String getTitle(Component parent) {
PopupFileName popupFileName = new PopupFileName();
int response = JOptionPane.showConfirmDialog(parent, popupFileName, "Title", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
switch (response) {
case JOptionPane.OK_OPTION:
return popupFileName.getTitle();
default: return null;
}
}
}
}

Why won't the JButtons, JLabels and JTextFields be displayed?

This code enables an employee to log in to the coffee shop system. I admit I have a lot of unneeded code. My problem is that when I run the program just the image is displayed above and no JButtons, JLabels or JTextFields.
Thanks in advance.
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.ImageIcon;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import java.awt.image.BufferedImage;
import java.net.URL;
import javax.imageio.ImageIO;
public class login extends JFrame {
public void CreateFrame() {
JFrame frame = new JFrame("Welcome");
JPanel panel = new JPanel();
panel.setOpaque(true);
panel.setBackground(Color.WHITE);
panel.setLayout(new BorderLayout(1000,1000));
panel.setLayout(new FlowLayout());
getContentPane().add(panel);
ImagePanel imagePanel = new ImagePanel();
imagePanel.show();
panel.add(imagePanel, BorderLayout.CENTER);
frame.setContentPane(panel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
frame.add(panel);
}
public static void main(String... args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
new login().CreateFrame();
}
});
}
}
class GUI extends JFrame{
private JButton buttonLogin;
private JButton buttonNewUser;
private JLabel iUsername;
private JLabel iPassword;
private JTextField userField;
private JPasswordField passField;
public void createGUI(){
setLayout(new GridBagLayout());
JPanel loginPanel = new JPanel();
loginPanel.setOpaque(false);
loginPanel.setLayout(new GridLayout(3,3,3,3));
iUsername = new JLabel("Username ");
iUsername.setForeground(Color.BLACK);
userField = new JTextField(10);
iPassword = new JLabel("Password ");
iPassword.setForeground(Color.BLACK);
passField = new JPasswordField(10);
buttonLogin = new JButton("Login");
buttonNewUser = new JButton("New User");
loginPanel.add(iUsername);
loginPanel.add(iPassword);
loginPanel.add(userField);
loginPanel.add(passField);
loginPanel.add(buttonLogin);
loginPanel.add(buttonNewUser);
add(loginPanel);
pack();
Writer writer = null;
File check = new File("userPass.txt");
if(check.exists()){
//Checks if the file exists. will not add anything if the file does exist.
}else{
try{
File texting = new File("userPass.txt");
writer = new BufferedWriter(new FileWriter(texting));
writer.write("message");
}catch(IOException e){
e.printStackTrace();
}
}
buttonLogin.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
try {
File file = new File("userPass.txt");
Scanner scan = new Scanner(file);;
String line = null;
FileWriter filewrite = new FileWriter(file, true);
String usertxt = " ";
String passtxt = " ";
String puname = userField.getText();
String ppaswd = passField.getText();
while (scan.hasNext()) {
usertxt = scan.nextLine();
passtxt = scan.nextLine();
}
if(puname.equals(usertxt) && ppaswd.equals(passtxt)) {
MainMenu menu = new MainMenu();
dispose();
}
else if(puname.equals("") && ppaswd.equals("")){
JOptionPane.showMessageDialog(null,"Please insert Username and Password");
}
else {
JOptionPane.showMessageDialog(null,"Wrong Username / Password");
userField.setText("");
passField.setText("");
userField.requestFocus();
}
} catch (IOException d) {
d.printStackTrace();
}
}
});
buttonNewUser.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
NewUser user = new NewUser();
dispose();
}
});
}
}
class ImagePanel extends JPanel{
private BufferedImage image;
public ImagePanel(){
setOpaque(true);
setBorder(BorderFactory.createLineBorder(Color.BLACK,5));
try
{
image = ImageIO.read(new URL("https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcQ8F5S_KK7uelpM5qdQXuaL1r09SS484R3-gLYArOp7Bom-LTYTT8Kjaiw"));
}
catch(Exception e)
{
e.printStackTrace();
}
GUI show = new GUI();
show.createGUI();
}
#Override
public Dimension getPreferredSize(){
return (new Dimension(430, 300));
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(image,0,0,this);
}
}
Seems to me like you have a class login (which is a JFrame, but never used as one). This login class creates a new generic "Welcome" JFrame with the ImagePanel in it. The ImagePanel calls GUI.createGUI() (which creates another JFrame, but doesn't show it) and then does absolutely nothing with it, thus it is immediately lost.
There are way to many JFrames in your code. One should be enough, perhaps two. But you got three: login, gui, and a simple new JFrame().

Wrapping JLabels inside a JPanel thats inside a JScrollPane

My Java is a bit rusty so please bear with me. I have a method in my GUI class that calls another class file which returns a JList. The problem im having is getting the text from the JList, you can see an example of the output below
package com.example.tests;
import java.awt.Color;
import java.awt.Container;
import java.awt.EventQueue;
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.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import com.example.tests.IJ_runTestAFJ;
public class GUI_v2 extends JFrame
{
private static final long serialVersionUID = 1L;
IJ_CommonSetup setup = new IJ_CommonSetup();
Container c;
JPanel panel;
JScrollPane userScrollPane, errorScrollPane, sysScrollPane;
JTextArea tfUserError, tfSysError;
private JButton resetButton;
public JList<String> errorList;
GUI_v2()
{
resetButton = new JButton();
resetButton.setText("Click to populate TextArea");
resetButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
//test.runTest_Login(stUserName,stPwd);
updatePanel();
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
panel = new JPanel();
tfSysError = new JTextArea(10,33);
tfSysError.setLineWrap(true);
tfSysError.setEditable(false);
tfSysError.setWrapStyleWord(false);
sysScrollPane = new JScrollPane(tfSysError);
sysScrollPane.setBorder(BorderFactory.createLineBorder(Color.black));
panel.add(sysScrollPane);
panel.add(resetButton);
c = getContentPane();
c.add(panel);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
setSize(400,250); //width, height
setLocation(600,0);
setResizable(false);
validate();
}//close GUI
/**
* #param args the command line arguments
*/
public static void main(String args[]) {
/* Create and display the form */
EventQueue.invokeLater(new Runnable() {
public void run() {
new GUI_v2().setVisible(true);
}
});
}
public void updatePanel()
{
errorList = new JList<String>();
errorList = setup.getErrorJList();
tfSysError.append(errorList.getComponent(1).toString());
validate();
}
}// end on class
IJ_CommonSetup.java
package com.example.tests;
import javax.swing.JLabel;
import javax.swing.JList;
public class IJ_CommonSetup{
/**
*
*/
public static String stError = new String();
public static JList<String> stJListError = new JList<String>();
public JList<String> getErrorJList(){
String error1 = new String("TestTestTestTestTestTestTestTestTestTestTestTestTestTest ");
String error2 = new String("ApplesApplesApplesApplesApplesApplesApplesApplesApplesApples ");
JLabel newError1 = new JLabel();
newError1.setText(error1);
JLabel newError2 = new JLabel(error2);
stJListError.add(newError1);
stJListError.add(newError2);
return stJListError;
}
}
im having some trouble getting labels to wrap inside a panel that's
inside a Scrollpane. At the moment if the string thats added to the
label is long it is aligned to the left which is fine but the label
stretches outside the panel cutting off the end of the string.
use JTextArea(int, int) in JScrollPane
setEditable(false) for JTextArea
instead of JLabels added to JPanel (in JScrollPane)
Normal text in a JLabel doesn't wrap. You can try using HTML:
String text = "<html>long text here</html";

Categories