I'm making this grade keeping program for my computer science class and the one thing I haven't gotten to work is saving/loading sessions. As I have it set up now it automatically saves when you exit and loads when you start if there is a file to load. However, I feel I'm loading or saving it incorrectly; there's one main JFrame that holds all the data, and that's the one object that is saved. When it's loaded, well, it'd be easier to show you.
If it looks like this when I close it::
Then it'll look like this when I start it up again:
Also, the "Enter Student" button, as well as the ActionListener on the JTextField used for input, cease to work when the program loads the JFrame. The program is split into 3 class files:
Gradebook:
import javax.swing.*;
import java.awt.event.*;
import java.io.*;
public class GradeBook implements java.io.Serializable {
private static JFrame frame;
public static void main(String[] args) throws Exception{
try{
FileInputStream fis = new FileInputStream("t.tmp");
ObjectInputStream ois = new ObjectInputStream(fis);
frame = (JFrame) ois.readObject();
ois.close();
} catch(Throwable t) {
frame = new JFrame("Course Grades");
}
frame.addWindowListener(new closing());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new CourseGrade());
frame.pack();
frame.setVisible(true);
}
closing:
private static class closing extends WindowAdapter {
public void windowClosing(WindowEvent e) {
try {
FileOutputStream fos = new FileOutputStream("t.tmp");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(frame);
oos.close();
} catch(Throwable t){System.out.println(t.getMessage());}
}
}
}
CourseGrade:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.FlowLayout;
import java.util.Random;
import javax.swing.table.*;
import java.io.*;
public class CourseGrade extends JPanel implements java.io.Serializable {
private JLabel entername;
private JTextField in;
private JTextArea list;
private JScrollPane scroll;
private String[] students = new String[1000];
private JButton enter;
private JButton[] studentbuttons = new JButton[1000];
private JButton[] delete=new JButton[1000];
private int numstudents;
private JFrame[] studentframes=new JFrame[1000];
private static JTable[] tables=new JTable[1000];
private static DefaultTableModel[] model=new DefaultTableModel[1000];
private static int[] numass=new int[1000];
public CourseGrade() {
String[][] data = {{"", "", "", ""}};
String[] headers = {"Assignment", "Date Assigned", "Score", "Percentage"};
for(int i=0; i<tables.length; i++){
model[i] = new DefaultTableModel(data, headers);
tables[i] = new JTable(model[i]){
public boolean isCellEditable(int rowIndex, int colIndex) {
return false;
}
};
}
numstudents=0;
in=new JTextField(13);
in.addActionListener(new enterListener());
list=new JTextArea();
scroll=new JScrollPane(list);
list.setEditable(false);
entername=new JLabel("Enter a student's name");
enter=new JButton("Enter Student");
enter.addActionListener(new enterListener());
setPreferredSize(new Dimension(260, 300));
setBackground(Color.green);
add(entername);
add(in);
add(enter);
add(scroll);
scroll.setPreferredSize(new Dimension(240, 200));
}
private class enterListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
String x=in.getText();
String y="";
String z="";
in.setText("");
int a=numstudents+1;
if(x.length()>0) x=a+". " + x + "\n";
students[numstudents] = x;
if(x.length()>0)numstudents++;
for(int i=0; i<numstudents; i++){
x=students[i];
if(x.length()>13)x=x.substring(0,11)+"...\n";
y+=x;
}
studentbuttons[numstudents]=new JButton("Edit");
studentbuttons[numstudents].addActionListener(new grades());
delete[numstudents]=new JButton("Delete");
delete[numstudents].addActionListener(new del());
list.setText(y);
list.add(studentbuttons[numstudents]);
studentbuttons[numstudents].setBounds(100,(numstudents-1)*16,55,15);
list.add(delete[numstudents]);
delete[numstudents].setBounds(160,(numstudents-1)*16,70,15);
}
}
private class grades implements ActionListener {
public void actionPerformed(ActionEvent event) {
Object obj = event.getSource();
if(obj instanceof JButton){
JButton clicked = (JButton)obj;
int x=clicked.getY()/16;
String y=students[x];
for(int i=0; i<y.length(); i++){
String q=y.substring(i,i+1);
if(q.equals(" ")) {
y=y.substring(i+1);
i=y.length()+1;
}
}
studentframes[x]=new JFrame(y+"'s Grades");
studentframes[x].setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
try{studentframes[x].getContentPane().add(new GradePage(x, tables[x], numass[x]));}
catch(Exception e){}
studentframes[x].pack();
studentframes[x].setVisible(true);
}
}
}
private class del implements ActionListener {
public void actionPerformed(ActionEvent event) {
Object obj = event.getSource();
if(obj instanceof JButton){
JButton clicked = (JButton)obj;
int x=clicked.getY()/16;
String y="", z="";
studentbuttons[numstudents].setVisible(false);
delete[numstudents].setVisible(false);
numstudents--;
int q=3;
int w=0;
for(int i=x; i<=numstudents; i++){
if(i<10)q=1;
else if(i<100) q=2;
tables[i]=tables[i+1];
numass[i]=numass[i+1];
model[i]=model[i+1];
w=i+1;
try{if(!students[i+1].equals(null)){students[i]=w+students[i+1].substring(q);} else{students[i]=null;}}catch(Throwable t){}
}
for(int i=0; i<numstudents; i++){
y=students[i];
if(y.length()>13)y=y.substring(0,11)+"...\n";
z+=y;
}
list.setText(z);
}
}
}
public static void setTable(int numtable, JTable table){
tables[numtable]=table;
}
public static void newRow(int numtable){
model[numtable].addRow(new Object[]{"", "", "", ""});
}
public static void setNumEntries(int numtable, int num){
numass[numtable]=num;
}
}
The third class shouldn't have anything to do with this so I wont post it for now.
I realize the code is probably poorly written but I'm only in my second year of High School computer science and we haven't actually covered any of this. This program wasn't even supposed to be a GUI, and this is the first time I've even heard of Input or Output streams so I really don't know anything about them. I realize now that having the classes implement java.io.Serializable was probably unnecessary but when I was trying to research this I came across someone taking about how some objects can't be saved because they don't naturally implement it. So sorry if it's some stupid mistake, and thanks for your time.
You can store the data in a notepad file like this
try
{
FileWriter file = new FileWriter( "insert file name here" );
BufferedWriter buffer = new BufferedWriter( file ) ;
buffer.write( "insert file content here" ) ;
buffer.newLine();
buffer.close();
}
catch ( IOException e )
{
//Insert error message here
}
And then read it like this
try
{
FileReader file = new FileReader( "insert file name here" ) ;
BufferedReader buffer = new BufferedReader( file );
String line = "" ;
while( ( line = buffer.readLine() ) != null )
{
System.out.println( line ) ;
}
buffer.close() ;
}
catch( IOException e )
{
//Insert error message here
}
Hope that helps
i dont recomend that you save JFrame object. here is a better solution you can save the students name and there grades on a text file and each time your program loads it will load the information from the text file.
Hint : you can use Input & Output streams dirctly but it's maybe a little bit sonfusing so go and read about these two classes :
Scanner (and how to use it to read from file)
PrintWriter (and how to use it to write to file)
P.S.: i could'v given you the code but it is much better learning experience to suffer a little bit to find information, because while you are trying to figure it out you will learn a lot of other things.
The frame is not an integral part of your application's state, it's just a way of displaying the important information (names, grades, etc). If you want to save your session, save the information the is currently on the screen and then re-create the JFrame with the deserialized information. An ObjectOutputStream is a reasonable way of writing things to disk, and and ObjectInputStream is good for reading the data back in. The documentation contains good examples. Also, your classes would need to implement Serializable.
Related
My GUI application allows users to type into a JTextField object stating the name of a file to open and display its contents onto a JTextArea object. If the entered information consists of the file name then it shall retrieve its contents otherwise, in other case, it shall be a directory then it shall display the files and folders. Right now, I'm stuck as in the setText() of my JTextArea does not display contents correctly. It only display once which means to say there's some problem with my while loop. Could you guys help me out here please?
Please note the code below has been altered to the correct working version provided all the helpful contributors below.
Main class:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
class MyFileLister extends JPanel implements ActionListener {
private JLabel prompt = null;
private JTextField userInput = null;
private JTextArea textArea = null;
public MyFileLister()
{
prompt = new JLabel("Enter filename: ");
prompt.setOpaque(true);
this.add(prompt);
userInput = new JTextField(28);
userInput.addActionListener(this);
this.add(userInput);
textArea = new JTextArea(10, 30);
textArea.setOpaque(true);
JScrollPane scrollpane = new JScrollPane(textArea);
this.add(textArea, BorderLayout.SOUTH);
}
Scanner s = null;
File af = null;
String[] paths;
public void actionPerformed(ActionEvent f)
{
try
{
s = new Scanner(new File(userInput.getText()));
while(s.hasNextLine())
{
String as = s.nextLine();
textArea.append(as + "\n");
textArea.setLineWrap(truea);
}
}
catch(FileNotFoundException e)
{
af = new File(userInput.getText());
paths = af.list();
System.out.println(Arrays.toString(paths));
String tempPath = "";
for(String path: paths)
{
tempPath += path + "\n";
}
textArea.setText(tempPath);
}
}
}
Driver class:
import java.util.*;
import java.awt.*;
import javax.swing.*;
class TestMyFileLister {
public static void main(String [] args)
{
MyFileLister thePanel = new MyFileLister();
JFrame firstFrame = new JFrame("My File Lister");
firstFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
firstFrame.setVisible(true);
firstFrame.setSize(500, 500);
firstFrame.add(thePanel);
}
}
Here's one of the screenshot which I have to achieve. It shows that when the user's input is on a directory it displays the list of files and folders under it.
I tried to put in an if statement to see if I can slot in a show message dialog but I seriously have no idea where to put it.
public void actionPerformed(ActionEvent f)
{
try
{
s = new Scanner(new File(userInput.getText()));
if(af == null)
{
System.out.println("Error");
}
while(s.hasNextLine())
{
String as = s.nextLine();
textArea.append(as + "\n");
textArea.setLineWrap(true);
}
}
catch(FileNotFoundException e)
{
af = new File(userInput.getText());
paths = af.list();
System.out.println(Arrays.toString(paths));
String tempPath = "";
for(String path: paths)
{
tempPath += path + "\n";
}
textArea.setText(tempPath);
}
}
You're outputting text to textArea based on the Last File on the list !!! ( don't set your text to JTextArea directly inside a loop, the loop is fast and the UI can't render it, so concatenate the string then set it later after the loop finishes ).
// These lines below are causing only last file shown.
for(String path: paths)
{
textArea.setText(path);
}
Here is your modified version for MyFileLister class :
public class MyFileLister extends JPanel implements ActionListener {
private JLabel prompt = null;
private JTextField userInput = null;
private JTextArea textArea = null;
public MyFileLister()
{
prompt = new JLabel("Enter filename: ");
prompt.setOpaque(true);
this.add(prompt);
userInput = new JTextField(28);
userInput.addActionListener(this);
this.add(userInput);
textArea = new JTextArea(10, 30);
textArea.setOpaque(true);
JScrollPane scrollpane = new JScrollPane(textArea);
this.add(scrollpane, BorderLayout.SOUTH);
}
Scanner s = null;
File af ;
String[] paths;
public void actionPerformed(ActionEvent f)
{
try
{
s = new Scanner(new File(userInput.getText()));
while(s.hasNext())
{
String as = s.next();
textArea.setText(as);
}
}
catch(FileNotFoundException e)
{
af = new File(userInput.getText());
paths = af.list();
System.out.println(Arrays.toString(paths));
String tempPath="";
for(String path: paths)
{
tempPath+=path+"\n";
}
textArea.setText(tempPath);
}
}
}
Output :
Code:
public void actionPerformed(ActionEvent ae) {
try (Scanner s = new Scanner(new File(userInput.getText()))) {
while (s.hasNextLine()) {
String as = s.nextLine();
textArea.append(as + "\n");
textArea.setLineWrap(true);
}
} catch (FileNotFoundException e) {
JOptionPane.showMessageDialog(this,
"File not found",
"No File Error",
JOptionPane.ERROR_MESSAGE);
}
}
Notes:
Just try to read your file line by line so you can copy the same structure from your file into your JTextArea.
Use setLineWrap method and set it to true
read here http://docs.oracle.com/javase/7/docs/api/javax/swing/JTextArea.html#setLineWrap(boolean)
use append method in order to add text to end of your JTextArea
read here
http://docs.oracle.com/javase/7/docs/api/javax/swing/JTextArea.html#append(java.lang.String)
Use JOptionPane to show error message to an user
I'm new to Java and have set myself the task of trying to create a simple calculator (and GUI) to advance my understanding and skills of the language.
Take this code:
import java.awt.FlowLayout;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class calc extends JFrame {
public JTextField input;
public JTextField output;
public JPanel Window;
public JButton math_button[] = new JButton[5];
public JButton number_button[] = new JButton[10];
public String[] number_button_name = {"1","2","3","4","5","6","7","8","9","0"};
public String[] name = {"Add", "Mulitply", "Divide", "Subtract", "Equals"};
public JFrame frame = new JFrame();
public JPanel math_panel = new JPanel();
public JPanel number_panel = new JPanel();
public JTextField math_input = new JTextField();
boolean trrgger = false;
thehandler handler = new thehandler();
public void go()
{
for(int b=0; b<number_button.length; b++)
{
number_button[b] = new JButton(number_button_name[b]);
number_button[b].addActionListener(handler);
number_panel.add(number_button[b]);
}
for(int i=0; i<math_button.length;i++)
{
math_button[i] = new JButton(name[i]);
math_button[i].addActionListener(handler);
math_panel.add(math_button[i]);
}
frame.getContentPane().add(BorderLayout.NORTH, math_input);
frame.getContentPane().add(BorderLayout.SOUTH, math_panel);
frame.getContentPane().add(BorderLayout.CENTER, number_panel);
frame.setSize(400,400);
frame.setVisible(true);
}
//Method to handle the math and return the results of whichever 'button' was pressed
static int Math(String button_num, int first_num, int second_num)
{
int total = 0;
if(button_num == "Add")
{
total = first_num + second_num;
}
else if (button_num == "Mulitply") //multiply
{
total = first_num * second_num;
}
else if (button_num == "Divide") //divide
{
total = first_num / second_num;
}
else if (button_num == "Substract") //subtract
{
total = first_num - second_num;
}
else if (button_num == "Equals") //subtract
{
total = total;
}
return total;
}
//Action Events - Code that is triggered once the associated button is clicked
public class thehandler implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
for (int h = 0; h <math_button.length; h++)
{
if(event.getSource()==math_button[h])
{
int firstn = Integer.parseInt(math_input.getText());
math_input.setText("");
int secondn = Integer.parseInt(math_input.getText());
System.out.println(calc.Math(math_button[h].getText(), firstn, secondn));
}
}
for(int n=0; n<number_button.length; n++)
{
if(event.getSource()==number_button[n])
{
String number_clicked = (number_button[n].getText());
String number = math_input.getText();
math_input.setText(number + number_clicked);
}
}
}
}
}
The idea behind this code is to create a simple GUI and allows the user to input the desired amount of numbers and then press the 'equals' button to display the result. However, as stated I'm having a problem with the logic. I can get the first entered number from the JTextField, clear the text once the first variable has been initialized but this is where the program falls over. The variable 'second_num' is passed to the 'Math' method as blank (which throws up errors) because that's what I tell the ActionEvent to do in order to allow for more fluid use of the program, no user wants to have to keep clearing the input box when using a calculator.
Anybody got any ideas?
Thanks
int firstn = Integer.parseInt(math_input.getText());
math_input.setText("");
int secondn = Integer.parseInt(math_input.getText());
What exactly do you expect the above lines to do? You are getting the text from math_input. Then you set it to an empty string. And by immediately getting the string back you are expecting to get something other than empty string?
The correct approach would be:
First time the handler is called (i.e. a "math" button is clicked) collect the input. Store it somewhere.
Next time this handler will be called you will have your next input. And so on until the user clicks on "=" to evaluate the whole expression.
Advice: If you are new to java, you might find it easier to create a calculator on the command line first. The functionality of a calculator does not require a GUI. In command line collecting the input is more simple. If you get that working then you can proceed to more fancy stuff like Swing
I looked at your code but its sound complicated for me. I recommend you to use IDE like Netbeans. Create swing application. To add two number all you need to do is as follow
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
int input_1 = Integer.parseInt(jTextField1.getText());
int input_2 = Integer.parseInt(jTextField2.getText());
jTextField3.setText(String.valueOf((input_1+input_2)));
}
http://i.stack.imgur.com/1G4v7.jpg
I am using a gui with JTextFields to collect some information and then a JButton that takes that infomration and writes it to a file, sets the gui visibility to false, and then uses Runnable to create an instance of another JFrame from a different class to display a slideshow.
I would like to access some of the information for the JTextFields from the new JFrame slideshow. I have tried creating an object of the previous class with accessor methods, but the values keep coming back null (I know that I have done this correctly).
I'm worried that when the accessor methods go to check what the variables equal the JTextFields appear null to the new JFrame.
Below is the sscce that shows this problem.
package accessmain;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
public class AccessMain extends JFrame implements ActionListener
{
private static final int FRAMEWIDTH = 800;
private static final int FRAMEHEIGHT = 300;
private JPanel mainPanel;
private PrintWriter outputStream = null;
private JTextField subjectNumberText;
private String subjectNumberString;
public static void main(String[] args)
{
AccessMain gui = new AccessMain();
gui.setVisible(true);
}
public AccessMain()
{
super("Self Paced Slideshow");
setSize(FRAMEWIDTH, FRAMEHEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
//Begin Main Content Panel
mainPanel = new JPanel();
mainPanel.setBorder(new EmptyBorder(0,10,0,10));
mainPanel.setLayout(new GridLayout(7, 2));
mainPanel.setBackground(Color.WHITE);
add(mainPanel, BorderLayout.CENTER);
mainPanel.add(new JLabel("Subject Number: "));
subjectNumberText = new JTextField(30);
mainPanel.add(subjectNumberText);
mainPanel.add(new JLabel(""));
JButton launch = new JButton("Begin Slideshow");
launch.addActionListener(this);
mainPanel.add(launch);
//End Main Content Panel
}
#Override
public void actionPerformed(ActionEvent e)
{
String actionCommand = e.getActionCommand();
if(actionCommand.equals("Begin Slideshow"))
{
subjectNumberString = subjectNumberText.getText();
if(!(subjectNumberString.equals("")))
{
System.out.println(getSubjectNumber());
this.setVisible(false);
writeFile();
outputStream.println("Subject Number:\t" + subjectNumberString);
outputStream.close();
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
AccessClass testClass = new AccessClass();
testClass.setVisible(true);
}
});
}
else
{
//Add warning dialogue here later
}
}
}
private void writeFile()
{
try
{
outputStream = new PrintWriter(new FileOutputStream(subjectNumberString + ".txt", false));
}
catch(FileNotFoundException e)
{
System.out.println("Cannot find file " + subjectNumberString + ".txt or it could not be opened.");
System.exit(0);
}
}
public String getSubjectNumber()
{
return subjectNumberString;
}
}
And then creating a barebones class to show the loss of data:
package accessmain;
import javax.swing.*;
import java.awt.*;
public class AccessClass extends JFrame
{
AccessMain experiment = new AccessMain();
String subjectNumber = experiment.getSubjectNumber();
public AccessClass()
{
System.out.println(subjectNumber);
}
}
Hardcoding the accessor method with "test" like this:
public String getSubjectNumber()
{
return "test";
}
Running this method as below in the new JFrame:
SelfPaceMain experiment = new SelfPaceMain();
private String subjectNumber = experiment.getSubjectNumber();
System.out.println(subjectNumber);
Does cause the system to print "test". So the accessor methods seem to be working. However, trying to access the values from the JTextFields doesn't seem to work.
I would read the information from the file I create, but without being able to pass the subjectNumber (which is used as the name of the file), I can't tell the new class what file to open.
Is there a good way to pass data from JTextFields to other classes?
pass the argument 'AccessMain' or 'JTextField' to the second class:
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
AccessClass testClass = new AccessClass(AccessMain.this); //fixed this
testClass.setVisible(true);
}
});
Then reading the value of 'subjectNumber'(JTextField value) from the 'AccessMain' or 'JTextField' in the second class:
public class AccessClass extends JFrame
{
final AccessMain experiment;
public AccessClass(AccessMain experiment)
{
this.experiment = experiment;
}
public String getSubjectNumber(){
return experiment.getSubjectNumber();
}
}
Also, you should try Observer pattern.
A simple demo of Observalbe and Observer
Observable and Observer Objects
How to put a dropdown list that has the list of every string, and when I select a item on that list then push the load button it will only show up what's on that String. Here's my code, I actually put the number of the string and and show the String's data using while statements.
How can I actually put a Dropdown list and it's content will be a number registered on every string. Just like this
1 231231
2 123124
3 123124
4 232312
If I select 4 and press "Load" it will show "232312"
and everytime I save a data a unique number will be registered in every line, just like
"4" is the unique no. and 232312 is it's data
package datasaving;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import javax.swing.*;
public class Datasaving {
/**
* #param args the command line arguments
* #throws FileNotFoundException
* #throws IOException
*/
public static void main(String[] args) throws FileNotFoundException, IOException {
JPanel panel = new JPanel();
JFrame frame = new JFrame();
final JTextField input0 = new javax.swing.JTextField(20);
final JTextField input1 = new javax.swing.JTextField(20);
final JTextField out = new javax.swing.JTextField(20);
final JTextField line = new javax.swing.JTextField(20);
JButton save = new javax.swing.JButton("Save");
JButton load = new javax.swing.JButton("Load");
frame.add(panel);
frame.setSize(240,200);
panel.add(input0);
panel.add(input1);
panel.add(save);
panel.add(line);
panel.add(out);
panel.add(load);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
save.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
File file = new File("data.dat");
try {
try (FileWriter writer = new FileWriter(file, true)) {
String data0 = input0.getText();
String data1 = input1.getText();
writer.write(data0+":"+data1+"\n");
}
System.out.println("Data Saved");
} catch (IOException | HeadlessException z) {
JOptionPane.showMessageDialog(null, e);
}
}
});
load.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int lines = Integer.parseInt(line.getText());
try {
FileInputStream fs= new FileInputStream("data.dat");
BufferedReader br = new BufferedReader(new InputStreamReader(fs));
for(int i = 0; i < lines; ++i) {
br.readLine();
}
out.setText(br.readLine());
JOptionPane.showMessageDialog(null, "Loaded");
} catch ( IOException | HeadlessException es) {
JOptionPane.showMessageDialog(null, e);
}
}
});
}
}
for example:
John blahblahblahblah
Keith blahblahblahblah
Joe blahblahblahblah
Kenneth blahblahblahblah
Christian blahblahblahblah
The first word "Names" will be added to JList or JComboBox
how to make the names a Array. I know how to use .split(); but I don't know how to make that happen in every lines in the file
1) JTextField doesn't support multi-line. Try JTextArea instead. With text areas, you can use myTextArea.append() to add lines as you read them.
2) But actually, it sounds like a JComboBox or a JList might be what you're really looking for:
http://docs.oracle.com/javase/tutorial/uiswing/components/combobox.html
3) Your basic program looks OK
'Hope that helps!
I'm trying to develop a Find and Replace like in Notepad. Here is my code so far for find. I am wondering how I can keep the dialog box open after pressing the button, so that I can use the dialog box for the next find.
import java.awt.BorderLayout;
import java.awt.event.*;
import java.io.FileInputStream;
import java.io.FileReader;
import java.util.Scanner;
import javax.swing.*;
class TextAreaEx extends JFrame implements ActionListener, KeyListener {
JButton button1;
JTextArea tx = new JTextArea();
int startFrom = 0;
int offset = 0;
String find = "";
String text = "";
TextAreaEx() {
super("My Frame");
FileInputStream fis = null;
StringBuffer sb = new StringBuffer();
try {
Scanner scan = new Scanner(new FileReader("C:\\Users\\Sam\\Desktop\\networktools.txt"));
while (scan.hasNext()) // while there's still something to read
{
tx.append(scan.nextLine() + "\n"); // append
}
} catch (Exception e) {
e.printStackTrace();
}
// text = sb.toString();
text = tx.getText();
text = text.toLowerCase();
button1 = new JButton("Find");
button1.addActionListener(this);
getContentPane().add(button1, BorderLayout.PAGE_START);
button1.setFocusable(false);
JScrollPane p1 = new JScrollPane(tx);
getContentPane().add(p1);
JFrame.setDefaultLookAndFeelDecorated(true);
tx.addKeyListener(this);
setSize(400, 400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocation(400, 300);
setVisible(true);
}
public static void main(String s[]) {
new TextAreaEx();
}
public void actionPerformed(ActionEvent e) {
startFrom = 0;
offset = 0;
if (e.getSource() == button1) {
find = (String) JOptionPane.showInputDialog(this, "FIND:\n", "Find", JOptionPane.INFORMATION_MESSAGE, null, null, null);
find = find.toLowerCase();
findWord();
this.setVisible(true);
}
}
public void findWord() {
offset = text.indexOf(find, startFrom);
if (offset > -1) {
tx.setFocusable(true);
tx.select(offset, find.length() + offset);
startFrom = find.length() + offset + 1;
} else {
JOptionPane.showMessageDialog(this, "No (more) matches");
}
}
public void keyPressed(KeyEvent ke) {
if (ke.getKeyCode() == KeyEvent.VK_F3) {
findWord();
}
}
public void keyReleased(KeyEvent ke) {
}
public void keyTyped(KeyEvent ke) {
}
}
Thanks for the help.
JOptionPane is meant to be used just to aks a simple question for the user to answer with yes/no, ok/cancel or ask the for simple input and than be closed.
"Real" find/replace dialog boxes need to do a lot more than this, don't try to use JOptionPane for this, it was not designed for that purpose.
You will need complete new dialog, (JFrame in you case) that can accomplish what you need, and you will be able to extend it to specify other options like "Match Case", use regular expressions and so on.
Notice: Aside from this your code needs A LOT of other improvements. Start with not using magic numbers and strings hard coded, name your variables appropriately ( and not button1 ) , stick up to the coding and formatting conventions in the language that you are using. Try to use smaller classes and methods that do just one thing - "A class should have one, and only one, reason to change". Try to extract to search functionality itself in its own class and write unit tests for it.
After time you could try to look at the some open source Java projects (JEdit is good example for editor) just to see how professional code looks like.
Good luck.