Highlighting changing text in a java swing jtextcomponent - java

I am trying to highlight some code in a JEditorPane like this:
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Highlighter;
public class Driver
{
public static void main(String[] args)
{
try
{
//create a simple frame with an editor pane
JFrame frame = new JFrame("Highlight Test");
JEditorPane pane = new JEditorPane();
frame.getContentPane().add(pane);
frame.setSize(300, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
//string to put in the pane
String text = "1234567890";
//grab the highlighter for the pane
Highlighter highlighter = pane.getHighlighter();
//store all the text at once
pane.setText(text);
//go through all the characters
for(int i = 0; i < text.length(); i++)
{
//highlight the latest character
highlighter.addHighlight(i, i + 1, DefaultHighlighter.DefaultPainter);
//sleep for a quarter second
Thread.sleep(250);
}
}catch(Exception ex){}
}
}
This will highlight the characters one at a time and all the characters will remain highlighted. Now, I'd like the same behavior (all the characters remain highlighted) but I'd like to change the text in between highlights, like this:
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Highlighter;
public class Driver
{
public static void main(String[] args)
{
try
{
//create a simple frame with an editor pane
JFrame frame = new JFrame("Highlight Test");
JEditorPane pane = new JEditorPane();
frame.getContentPane().add(pane);
frame.setSize(300, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
//string to put in the pane
String text = "1234567890";
//grab the highlighter for the pane
Highlighter highlighter = pane.getHighlighter();
//go through all the characters
for(int i = 0; i < text.length(); i++)
{
//place a new string in the pane
pane.setText(pane.getText() + text.charAt(i));
//highlight the latest character
highlighter.addHighlight(i, i + 1, DefaultHighlighter.DefaultPainter);
//sleep for a quarter second
Thread.sleep(250);
}
}catch(Exception ex){}
}
}
Notice the text in the pane is changing and then I'm applying a new highlight. The old highlights go away- I'd like them to stay. My assumption is the highlights go away each time you setText(). So, is there any way to keep the highlights in the text component while changing the text?

i didn't tried the following code but what i suggest is just try to highlight both latest character and previous ones too like this:
//go through all the characters
for(int i = 0; i < text.length(); i++)
{
//place a new string in the pane
pane.setText(pane.getText() + text.charAt(i));
//highlight the previous characters
if (i > 0) {
for ( int j=i-1; j >= 0; j--)
highlighter.addHighlight(j, j+1 , DefaultHighlighter.DefaultPainter);
}
//highlight the latest character
highlighter.addHighlight(i, i + 1, DefaultHighlighter.DefaultPainter);
//sleep for a quarter second
// Thread.sleep(250);
}
}catch(Exception ex){}

Related

Troubleshooting Vignere Cipher using JFileChooser and JPasswordField

I'm attempting to make a code that will use JFileChooser and JPassword for getting input of encrypted code or code to be encrypted.
Here is the code to be encrypted "Be sure to drink your Ovaltine!" to be saved in a .rtf or a .txt file. The key is "annie". The output should be
"Fv '$zi (# pzm"| (wy& `%ip(zzm%".
I have two different class files under the project "Password". One class is called "File Opener". It calls the class "Password1".
Here is Password1.java.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Arrays;
/* PasswordDemo.java requires no other files. */
public class Password1 extends JPanel
implements ActionListener {
private String key;
private static String OK = "ok";
private JFrame controllingFrame; //needed for dialogs
private JPasswordField passwordField;
public Password1(JFrame f) {
//Use the default FlowLayout.
controllingFrame = f;
//Create everything.
passwordField = new JPasswordField(10);
passwordField.setActionCommand(OK);
passwordField.addActionListener(this);
JLabel label = new JLabel("Enter the key: ");
label.setLabelFor(passwordField);
JComponent buttonPane = createButtonPanel();
//Lay out everything.
JPanel textPane = new JPanel(new FlowLayout(FlowLayout.TRAILING));
textPane.add(label);
textPane.add(passwordField);
add(textPane);
add(buttonPane);
}
protected JComponent createButtonPanel() {
JPanel p = new JPanel(new GridLayout(0,1));
JButton okButton = new JButton("OK");
okButton.setActionCommand(OK);
okButton.addActionListener(this);
p.add(okButton);
return p;
}
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
controllingFrame.dispose();
if (OK.equals(cmd)) { //Process the password.
char[] input = passwordField.getPassword();
key = new String(input);
//Zero out the possible password, for security.
Arrays.fill(input,'0');
passwordField.selectAll();
resetFocus();
} else {
System.out.println("Please enter a key.");
}
}
public String getKey(){
return key;
}
//Must be called from the event dispatch thread.
protected void resetFocus() {
passwordField.requestFocusInWindow();
}
public static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("Key");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
final Password1 newContentPane = new Password1(frame);
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Make sure the focus goes to the right component
//whenever the frame is initially given the focus.
frame.addWindowListener(new WindowAdapter() {
public void windowActivated(WindowEvent e) {
newContentPane.resetFocus();
}
});
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event dispatch thread:
//creating and showing this application's GUI.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
//Turn off metal's use of bold fonts
UIManager.put("swing.boldMetal", Boolean.FALSE);
createAndShowGUI();
}
});
}
}
And here is the FileOpener.java.
import javax.swing.*;
import java.io.*;
import javax.swing.filechooser.*;
import java.awt.event.*;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Scanner;
public class FileOpener extends JPanel implements ActionListener {
static private final String newline = "\n";
private Password1 p1;
JButton decodeButton, encodeButton;
JFileChooser fc;
JTextArea log;
Scanner in = new Scanner(System.in);
JFrame frame;
File file;
int count;
public FileOpener(){
// create and set up the window.
frame = new JFrame("Open Your File");
// make the program close when the window closes
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// create the box layout
frame.getContentPane( ).setLayout(new BoxLayout(frame.getContentPane( ), BoxLayout.Y_AXIS));
//label prompting user for input
JLabel label1 = new JLabel ("Would you like to encode or decode your file?", JLabel.CENTER);
frame.getContentPane().add(label1);
//create a filer chooser
fc = new JFileChooser();
// add a button object
decodeButton = new JButton("Decode");
decodeButton.addActionListener(this);
frame.getContentPane( ).add(decodeButton);
encodeButton = new JButton("Encode");
encodeButton.addActionListener(this);
frame.getContentPane( ).add(encodeButton);
// display the window.
frame.pack( );
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
//Handle open button action.
if (e.getSource() == encodeButton) {
frame.dispose();
int returnVal = fc.showOpenDialog(FileOpener.this);
if (returnVal == JFileChooser.APPROVE_OPTION ) {
try {
file = fc.getSelectedFile();
p1 = new Password1(frame);
p1.createAndShowGUI();
//get length of key
String key = p1.getKey();
int length3 = key.length();
count = 0;
int keyAsciiValues[] = new int[length3];
String name1 ="";
//get ascii value of each letter in key
for (int k=0; k<length3; k++){
char a = key.charAt(k);
int ascii1 = (int)a;
//put ascii value of letter in key to array
keyAsciiValues[k]= ascii1;
}
FileInputStream file2= new FileInputStream(file);
//create a scanner for it
in = new Scanner(file2);
//read in message
String name;
name = in.nextLine();
for (int k=0; k<length3; k++){
char a = key.charAt(k);
int ascii1 = (int)a;
//put ascii value of letter in key to array
keyAsciiValues[k]= ascii1;
}
//measure length of code message array
int length1 = name.length();
//measures length of strings in code message array
for(int j=0;j<length1;j++){
char c = name.charAt(j);
int ascii = (int)c;
ascii += keyAsciiValues[count];
if(c != ' '){
count++;
}
if(count>length3-1){
count = 0;
}
while(ascii>126){
ascii-= 93;
}
char b=(char)ascii;
if(c == ' '){
b = ' ';
}
name1 += b;
}
System.out.println(name1);
} catch (FileNotFoundException k){
//the file was not found!
System.out.println("File could not be opened!");
}
}
//Handle save button action.
} else if (e.getSource() == decodeButton) {
frame.dispose();
int returnVal = fc.showOpenDialog(FileOpener.this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
try {
file = fc.getSelectedFile();
p1 = new Password1(frame);
p1.createAndShowGUI();
//open the file
//get length of key
String key = p1.getKey();
int length3 = key.length();
count = 0;
int keyAsciiValues[] = new int[length3];
String name1 ="";
//get ascii value of each letter in key
for (int k=0; k<length3; k++){
char a = key.charAt(k);
int ascii1 = (int)a;
//put ascii value of letter in key to array
keyAsciiValues[k]= ascii1;
}
//create a scanner for it
in = new Scanner(file);
//read in message
String name;
name = in.nextLine();
for (int k=0; k<length3; k++){
char a = key.charAt(k);
int ascii1 = (int)a;
//put ascii value of letter in key to array
keyAsciiValues[k]= ascii1;
}
//measure length of code message array
int length1 = name.length();
//measures length of strings in code message array
for(int j=0;j<length1;j++){
char c = name.charAt(j);
int ascii = (int)c;
ascii -= keyAsciiValues[count];
if(c != ' '){
count++;
}
if(count>length3-1){
count = 0;
}
while(ascii<33){
ascii+= 93;
}
char b=(char)ascii;
if(c == ' '){
b = ' ';
}
name1 += b;
}
System.out.print(name1);
} catch (FileNotFoundException k){
//the file was not found!
System.out.println("File could not be opened!");
}
}
in.close();
log.append("Opening: " + file.getName() + "." + newline);
}
}
public static void main(String args[]) {
//Schedule a job for the event dispatch thread:
//creating and showing this application's GUI.
FileOpener f = new FileOpener();
}
}
It was working fine before I added the JFileChooser and the Password stuff aka there shouldn't be anything wrong with the actual ciphering part of the code.
It's giving me a java.lang.NullPointerException at line at line 70 in FileOpener.
int length3 = key.length();
Thanks!
In the createAndShowGUI() method, you show your Password1 instance in a JFrame, not a modal JDialog. Therefore, this display instruction is non-blocking, i.e. it does not stop code execution, nor does it wait until you click a button that closes the window.
As a result, you retrieve the Password1 instance key before its actionPerformed() method can execute and initialize the key attribute, hence the key is still null and you get a NullPointerException when you invoke any method on it.
My suggestion is using a modal JDialog in createAndShowGUI() to manage your Password1 interface (initialization using a JPanel is much like what you are already doing with a JFrame). This way, when you invoke createAndShowGUI(), the FileOpener.actionPerformed() method execution will block until you are done with the Password1 dialog, hence you will make sure key is properly initialized before you retrieve and use it in FileOpener.actionPerformed().
One last thing: be careful with frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);! Using it on your main window is OK but using it on any secondary window will make the whole program shut down completely as soon as you close it. But anyway, the JDialog version of setDefaultCloseOperation() doesn't accept EXIT_ON_CLOSE as a valid argument, so you will remain using it only on your main FileOpener window, which is fine.

ScrollPane adding to grid layout

in my code I am calling a few items(my buttons with their names leading to different project. The names and everything are taken from a database)
I want a J ScrollPane to surround my buttons, what can I do? I just want the buttons to be called inside the scroll pane. Here is my code
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class AdminClass implements ActionListener {
ProjectButton[] buttons = new ProjectButton[35];
//Creating data field for unique Ids in the form of array list
ArrayList<Integer> uniqueIDList = new ArrayList<Integer>();
String[] projectNames;
int[] uniqueIds;
Connection conn1 = null;
Statement stmt1 = null;
JFrame frame = new JFrame("Admin Panel");
private JPanel panel = new JPanel();
JButton btnNewButton = new JButton("Add New Project");
public AdminClass() {
panel.setLayout(new GridLayout(10, 1));
panel.add(new JLabel("Welcome to Admin Panel"));
btnNewButton.addActionListener(this);
panel.add(btnNewButton);
panel.add(new JLabel("Existing Projects"));
conn1 = sqliteConnection.dbConnector();
try{
Class.forName("org.sqlite.JDBC");
conn1.setAutoCommit(false);
stmt1 = conn1.createStatement();
ResultSet rs1 = stmt1.executeQuery( "SELECT * FROM Project;" );
List<String> projectNameList = new ArrayList<String>();
while ( rs1.next() ){
int id = rs1.getInt("uniqueid");
String projectName = rs1.getString("name");
projectNameList.add(projectName);
uniqueIDList.add(id);
}
// Converting array list to array
projectNames = new String[projectNameList.size()];
projectNameList.toArray(projectNames);
uniqueIds = convertIntegers(uniqueIDList);
rs1.close();
stmt1.close();
conn1.close();
}
catch ( Exception e1 ) {
JOptionPane.showMessageDialog(null, e1);
}
// Adding buttons to the project
try{
for (int i = 0; i < projectNames.length; i++){
buttons[i] = new ProjectButton(projectNames[i]);
buttons[i].setId(uniqueIds[i]);
panel.add(buttons[i]);
buttons[i].addActionListener(this);
}
}
catch (Exception e2){
JOptionPane.showMessageDialog(null, e2);
}
frame.add(panel);
frame.setVisible(true);
frame.setSize(500, 500);
}
public void actionPerformed(ActionEvent e) {
for (int j = 0; j < buttons.length; j ++){
if (e.getSource() == buttons[j]){
AdminStatus sc = new AdminStatus(buttons[j].getId());
frame.dispose();
}
}
if (e.getSource() == btnNewButton){
frame.dispose();
WindowProjectAdmin wpa = new WindowProjectAdmin();
}
}
//Method to convert integar array list to integar array
public int[] convertIntegers(List<Integer> integers)
{
int[] ret = new int[integers.size()];
for (int i=0; i < ret.length; i++)
{
ret[i] = integers.get(i).intValue();
}
return ret;
}
}
This may seem very normal but it's really not, for some reason they are not visible or are not called inside a scroller. Please edit my code maybe?
Start by adding the buttons to their own container, this way you can control the layout of the buttons separately from the rest of the UI
JPanel panelFullOfButtons = new JPanel();
try {
for (int i = 0; i < projectNames.length; i++) {
buttons[i] = new ProjectButton(projectNames[i]);
buttons[i].setId(uniqueIds[i]);
panelFullOfButtons.add(buttons[i]);
buttons[i].addActionListener(this);
}
} catch (Exception e2) {
JOptionPane.showMessageDialog(null, e2);
}
Then add the "main" panel to the NORTH position of the frame and the "buttons" panel to the CENTER
frame.add(panel, BorderLayout.NORTH);
frame.add(new JScrollPane(panelFullOfButtons), BorderLayout.CENTER);
Mind you, in this case, I'd be very tempted to use something like a JList instead. See How to Use Lists for more details
I have done the same, can you tell me what's wrong?
// Problem #1...
JScrollPane pane = new JScrollPane();
pane.add(buttonPanel);
//...
// Problem #2...
panel.add(pane);
frame.add(panel);
These are competing with each other, moving the content around and overlapping with existing content...
public AdminClass() {
panel.setLayout(new GridLayout(3, 1));
panel.add(new JLabel("Welcome to Admin Panel"));
btnNewButton.addActionListener(this);
panel.add(btnNewButton);
panel.add(new JLabel("Existing Projects"));
List<String> projectNameList = new ArrayList<String>();
for (int index = 0; index < 1000; index++) {
projectNameList.add("Project " + index);
}
projectNames = projectNameList.toArray(new String[0]);
// Adding buttons to the project
buttons = new JButton[projectNameList.size()];
try {
for (int i = 0; i < projectNames.length; i++) {
buttons[i] = new JButton(projectNames[i]);
btnPnl1.add(buttons[i]);
buttons[i].addActionListener(this);
}
} catch (Exception e2) {
JOptionPane.showMessageDialog(null, e2);
}
frame.add(panel, BorderLayout.NORTH);
frame.add(new JScrollPane(btnPnl1), BorderLayout.CENTER);
frame.setVisible(true);
frame.setSize(500, 500);
}
In this case I'd prefer to use either a JList to show the projects or a WrapLayout for laying out the buttons
Its useless to create a GridLayout like this: panel.setLayout(new GridLayout(10, 1));. If you declare the rows as a non zero value, the column count will be ignored. When you declare the maximum number of rows as ten, you force the eleventh component to be added in a second column (then a third, a forth and so on). Use panel.setLayout(new GridLayout(0, 1)); instead to force the only one column and frame.add(new JScrollPane(panel)); to create the ScrollPane.
But note that GridLayout will try to shrink your components the maximum as possible to fit the container size before scrolling is enabled.
I just want the button part to be inside J Scroll Pane
If you just want the JButton's (those added within the loop):
Create a new JPanel that you add the buttons to
Add (1) to a JScrollPane
Add (2) to panel
For example:
JPanel buttonPanel = new JPanel(new FlowLayout());
for (int i = 0; i < projectNames.length; i++){
buttons[i] = new ProjectButton(projectNames[i]);
buttons[i].setId(uniqueIds[i]);
panel.add(buttons[i]);
buttonPanel[i].addActionListener(this);
}
JScrollPane scroller = new JScrollPane(buttonPanel);
panel.add(scroller);
You might also consider using a different Component that doesn't require a JScrollPane, of course depending upon your needs - for instance a JComboBox.

Displaying an array of Strings in a JTextArea

i've been stuck on getting one of my JTextArea's to display an array of Strings that represent letters in a word in a hangman game. Once the user guesses a letter, (assuming it's right), it should reflect into the array. Instead, it seems to be only adding the letter that was guessed, and not the blanks or the rest of the array. I want to set the guessed letter equal to the correct index in the array and then have it shown on the screen. Here is my code:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
#SuppressWarnings("serial")
public class GuiClass extends JFrame {
char guess = ' ';
int numGuesses = 0;
char[] letterGuessedAgainst = null;
String wordInPlay = " ";
String[] hangmanScores = null;
ArrayList<Character> wrongGuesses = null;
boolean isGuessSuccessfull = false;
private Container contents;
JRadioButton rbEasy;
JRadioButton rbHard;
ButtonGroup difficultyGroup;
JTextField txtfldWord;
JTextArea txtareaWord;
JLabel difficultyPrompt;
JLabel userDifficulty;
JButton btnStartGame;
JButton btnGuessSubmit;
JButton btnWordGuessSubmit;
JPanel topPanel;
JPanel midPanel;
JLabel topLabel;
JPanel guessPanel;
JPanel letterPanel;
JLabel word;
JTextArea txtareaNumGuesses;
JTextField txtfldGuess;
JTextField txtfldWordGuess;
JTextArea txtareaguessedLetters;
JTextArea txtareaLettersLeft;
public GuiClass(){
super("Hangman GUI");
contents = getContentPane();
//create a new panel & set layout
midPanel = new JPanel();
midPanel.setLayout(new GridLayout(3,3));
//layout manager
topLabel = new JLabel("Welcome to Hangman!");
contents.setLayout(new FlowLayout());
//create new ButtonHandlers
ButtonHandler buttonHandler = new ButtonHandler();
ButtonHandler2 btnHndlrNewGame = new ButtonHandler2();
//create difficulty buttons/labels & add ActionListeners
difficultyPrompt = new JLabel("First, Choose A Difficulty:");
rbEasy = new JRadioButton("Easy");
rbHard = new JRadioButton("Hard");
userDifficulty = new JLabel("Game Difficulty: ");
difficultyGroup = new ButtonGroup();
difficultyGroup.add(rbEasy);
difficultyGroup.add(rbHard);
rbEasy.addItemListener(buttonHandler);
rbHard.addItemListener(buttonHandler);
midPanel.add(topLabel);
midPanel.add(difficultyPrompt);
midPanel.add(rbEasy);
midPanel.add(rbHard);
midPanel.add(userDifficulty);
topPanel = new JPanel();
JLabel btnStartNewGame = new JLabel("Next, Start a new game!");
btnStartGame = new JButton("Start A New Game");
btnStartGame.addActionListener(btnHndlrNewGame);
topPanel.add(btnStartNewGame);
topPanel.add(btnStartGame);
guessPanel = new JPanel();
JLabel lblGuess = new JLabel("Guess: ");
JLabel lblWordGuess = new JLabel("Word Guess: ");
btnGuessSubmit = new JButton("Submit");
btnGuessSubmit.addActionListener(btnHndlrNewGame);
btnWordGuessSubmit = new JButton("Submit");
btnGuessSubmit.addActionListener(btnHndlrNewGame);
txtfldGuess = new JTextField(10);
txtfldWordGuess = new JTextField(10);
guessPanel.add(lblGuess);
guessPanel.add(txtfldGuess);
guessPanel.add(btnGuessSubmit);
guessPanel.add(lblWordGuess);
guessPanel.add(txtfldWordGuess);
guessPanel.add(btnWordGuessSubmit);
letterPanel = new JPanel();
JLabel lblGuessedLetters = new JLabel("Guessed Letters:");
JLabel lblLettersInWord = new JLabel("Letters Left:");
JLabel lblNumGuesses = new JLabel("Guess Number: ");
txtareaNumGuesses = new JTextArea(5,5);
txtareaNumGuesses.setEditable(false);
txtareaguessedLetters = new JTextArea(5,15);
txtareaguessedLetters.setEditable(false);
txtareaLettersLeft = new JTextArea(5,15);
txtareaLettersLeft.setEditable(false);
letterPanel.add(lblGuessedLetters);
letterPanel.add(txtareaguessedLetters);
letterPanel.add(lblLettersInWord);
letterPanel.add(txtareaLettersLeft);
letterPanel.add(lblNumGuesses);
letterPanel.add(txtareaNumGuesses);
JPanel wordPanel = new JPanel();
word = new JLabel("Word is: ");
//txtfldWord = new JTextField(10);
txtareaWord = new JTextArea(20,20);
//txtfldWord.setEditable(false);
txtareaWord.setEditable(false);
wordPanel.add(word);
//wordPanel.add(txtfldWord);
wordPanel.add(txtareaWord);
//add contents of panels to the container
contents.add(midPanel);
contents.add(topPanel);
contents.add(guessPanel);
contents.add(letterPanel);
contents.add(wordPanel);
setSize(800,600);
setVisible(true);
}//end constructor
private class ButtonHandler implements ItemListener{
public void itemStateChanged(ItemEvent ie){
if (ie.getSource()==rbEasy){
userDifficulty.setText("Game Difficulty: Easy");
}//end if
if (ie.getSource()==rbHard){
userDifficulty.setText("Game Difficulty: Hard");
}//end if
}//end method
}//end ButtonHandler inner class
private class ButtonHandler2 implements ActionListener{
public void actionPerformed(ActionEvent ae){
if (ae.getSource()==btnStartGame){
if (rbEasy.isSelected()){
ArrayList<String> easyHmWords = new ArrayList<String>();
String filename = "easyhangmanwords.txt";
BufferedReader infile = null;
try {
infile = new BufferedReader(new FileReader(filename));
}//end try
catch (FileNotFoundException e) {
e.getMessage();
}//end catch
String re = "";
try {
while ((re=infile.readLine())!=null){ // reading one line
easyHmWords.add(re);
}//end while
System.out.println("words in file: "+easyHmWords);
}//end try
catch (IOException e) {
e.getMessage();
}//end while
try {
infile.close();
}//end try
catch (IOException e) {
e.getMessage();
}//end catch
wordInPlay = "";
int randomNumber = 0;
Random rand = new Random();
int maxRandomNumber = 0;
word.setText("Word is: Set");
//System.out.println("Okay, the word is set!");
maxRandomNumber = easyHmWords.size();
System.out.println("Size of arraylist: "+easyHmWords.size());
randomNumber = rand.nextInt(maxRandomNumber);
System.out.println("random num: "+randomNumber);
wordInPlay = easyHmWords.get(randomNumber);
System.out.println("word in play: "+wordInPlay);
//figures out how many letters the word has
int lettersInWord = wordInPlay.length();
System.out.println("Letters in word: "+lettersInWord);
//creates an array of hangman scores which is the size of the letters in the word
hangmanScores = new String[lettersInWord];
//for loop to iterate through the array and assign "_" to the spaces
for (int i = 0; i < hangmanScores.length; i++) {
hangmanScores[i] = " _ ";
}//end for
for (int i = 0; i < hangmanScores.length; i++){
//txtareaWord.setText(hangmanScores[i]);
//txtfldWord.append(hangmanScores[i]);
txtareaWord.append((hangmanScores[i]));
}//end for
}//end if
}//end if
if(btnGuessSubmit == ae.getSource()){ //getting problems in this if statement
guess = txtfldGuess.getText().charAt(0);
letterGuessedAgainst = wordInPlay.toCharArray();
for (int i = 0; i < letterGuessedAgainst.length; i++) {//goes through the letters of the word in play
***if(letterGuessedAgainst[i]==guess){//if a letter matches up,
hangmanScores[i] = Character.toString(guess);
isGuessSuccessfull = true;
}//end if
}//end for
for (int k =0; k < hangmanScores.length; k++){//displays the ______ in the text area
txtareaWord.setText((hangmanScores[k]));***
System.out.print(hangmanScores[k]);//testing purposes
}//end for
numGuesses++;
txtareaNumGuesses.setText(" "+numGuesses);
}//end for
if(isGuessSuccessfull = false){
wrongGuesses.add(guess);
txtareaguessedLetters.append(wrongGuesses+"");
}//end if
}//end method
}//end private inner class
public static void main (String[] args){
GuiClass estGUI = new GuiClass();
estGUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}//end main method
}//end class
this is the part of the code that doesn't display the correct parts of the array:
***if(letterGuessedAgainst[i]==guess){//if a letter matches up,
hangmanScores[i] = Character.toString(guess);
isGuessSuccessfull = true;
}//end if
}//end for
for (int k =0; k < hangmanScores.length; k++){
txtareaWord.setText((hangmanScores[k]));***
Basically, you are calling setText every time you want to add a new character to the JTextArea in question, this is, first, clearing any existing text and then adding the new String, which, in this case, is the last thing you entered.
There are a few ways you could fix this, but because you want to remove the existing text first and then replace it, it's probably better to build a buffer of what you want and apply it all in a single step...
StringBuilder sb = new StringBuilder(hangmanScores.length);
for (int k = 0; k < hangmanScores.length; k++) {//displays the ______ in the text area
sb.append(hangmanScores[k]);
System.out.print(hangmanScores[k]);//testing purposes
}//end for
txtareaWord.setText(sb.toString());
You also seem to have attached multiple ActionListeners to your button, as each time I clicked it, it counted for two guesses...

Minor glitch in the code

The below code is used to create a line graph. I am able to display the integers in the TextArea but i am not able to display the sentences above the integers in the text file. How do i rectify this program?
The screenshot of the text file is given below.
I want the first three lines of the text file also to be printed in the TextArea.
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.WindowConstants;
import org.jfree.chart.*;
import org.jfree.chart.plot.*;
import org.jfree.data.xy.*;
public class Pio {
static JFrame frame1 = new JFrame("Graph");
static String URL = null;
static JTextArea txt = new JTextArea();
static JPanel panel = new JPanel();
public static void main(String[] args) throws IOException {
JButton but = new JButton("Open file");
![enter image description here][2]
panel.add(but);
frame1.add(panel, BorderLayout.WEST);
frame1.setVisible(true);
frame1.setSize(1000,400);
but.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
JFileChooser chooser = new JFileChooser();
int ret = chooser.showDialog(null, "Open file");
if (ret == JFileChooser.APPROVE_OPTION)
{
File file = chooser.getSelectedFile();
URL = file.getAbsolutePath();
}
File f = new File(URL);
FileReader inputF = null;
try {
inputF = new FileReader(f);
}
catch (FileNotFoundException e1) {
e1.printStackTrace();
}
BufferedReader in = new BufferedReader(inputF);
int[] a = new int[100];
int[] b = new int[100];
String s=null;
try {
s = in.readLine();
}
catch (IOException e1) {
e1.printStackTrace();
}
int i = 0;
while (s != null && i < 100)
{ // your arrays can only hold 1000 ints
String pair[] = s.split(" ");
a[i] = Integer.parseInt(pair[0]);
b[i] = Integer.parseInt(pair[1]);
i++; // don't forget to increment
try {
s = in.readLine();
}
catch (IOException e1) {
e1.printStackTrace();
}
}
try {
in.close();
}
catch (IOException e1) {
e1.printStackTrace();
}
System.out.println("the output of the file is " + f);
XYSeries data = new XYSeries("Line Graph");
int n = a.length;
for (int j = 0; j < n; j++) {
data.add(a[j], b[j]);
}
XYDataset xY = new XYSeriesCollection(data);
JFreeChart chart=ChartFactory.createXYLineChart(
"line graph",
"Cycles",
"Temperature",
xY,
PlotOrientation.VERTICAL,
true,
true,
true);
ChartPanel p=new ChartPanel(chart);
p.setVisible(true);
p.setLocation(100,100);
p.setSize(500,500);
frame1.add(p,BorderLayout.EAST);
}
});
}
}
there nothing about JTextArea, use constructor JTextArea(int rows, int columns)
put JTextArea to the JScrollPane, this JScrollPane put or the EAST or WEST area
put JPanel with JButton to the SOUTH or NORTH area
if ChartPanel doesn't returns any PrefferedSize (I doubt that), or this value isn't correct, then set for own PrefferedSize, put ChartPanel to the CENTER area
as you saw there any code line about setSize, JFrame has implemented BorderLayout in the API
use pack() instead of setSize()
setLocation() if required
last code lines in the ActionListener (your code logics) must be
frame.validate();
frame.repaint();
frame.pack();
in this form (your code logics) is Swing GUI during FileIO unresponsible for Mouse and Key Events, wrap FileIO to the Runnable#Tread or use SwingWorker for redirecting this long and hard task to the background task
create ChartPanel as local variable (as JFrame) and first code line in the ActionListener must be
.
frame.remove(ChartPanel);
Two display two componenets you can use a JSplitPane.
While loading data into your array append it to a JTextArea (area1 in the sample code)
final JTextArea area1 = new JTextArea();
...
area1.append("X=" + a[i] + " Y=" + b[i] + "\n");
Then rather than adding the chart to the frame add both the Chart and the TextArea to the JSplitPane
ChartPanel p = new ChartPanel(chart);
JSplitPane splitpane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
frame1.add( splitpane , BorderLayout.CENTER );
splitpane.add(p);
splitpane.add(area1);
pane.validate();
frame1.validate();
frame1.repaint();
To append data the the JTextArea use
area1.append("Creating a line graph\n");
area1.append("Selected file " + f + "\n");
while (s != null && i < 100) { // your arrays can only hold 1000 ints
String pair[] = s.split(" ");
try{
a[i] = Integer.parseInt(pair[0]);
b[i] = Integer.parseInt(pair[1]);
area1.append("X=" + a[i] + " Y=" + b[i] + "\n");
} catch (NumberFormatException e) {
area1.append(s + "\n");
}
try {
s = in.readLine();
i++; // don't forget to increment
} catch (IOException e1) {
e1.printStackTrace();
}
}
area1.append("Finished reading data\n");
...
In this example I'm assuming that the headder will fail parseInt and (if is does) appending the String s.

Why does this code work in Vista but not 7?

For some reason every time I have someone run this program in Vista it works flawlessly but as soon as I move it over to a Windows 7 PC it stops in the middle of the ActionListener's Action Performed Method meaning I can click my choices but it will never say size selected.
Is there any way to fix this?
import java.io.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class SizerFrame extends JFrame {
ButtonGroup buttons = new ButtonGroup();
JTextField width = new JTextField(2);
JTextField height = new JTextField(2);
double inchesPerTimeline = 2.1;
public SizerFrame()
{
super("Timeline Application");
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
setBounds(screen.width/2-125,screen.height/2-90,250,180);
getContentPane().setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
int[] gridX = new int[]{0,0,0,0};
int[] gridY = new int[]{0,1,2,3};
int[] gridW = new int[]{1,1,2,5};
String[] titles = new String[]{"6\"","9\"","10\"","Custom"};
String[] actions = new String[]{"6","9","10","C"};
for (int a = 0; a < 4; a++)
{
JRadioButton current = new JRadioButton(titles[a]);
current.setActionCommand(actions[a]);
c.gridx = gridX[a];
c.gridy = gridY[a];
c.gridwidth = gridW[a];
buttons.add(current);
getContentPane().add(current,c);
}
c.gridwidth = 1;
String[] title = new String[]{" ","Width","Height"};
gridX = new int[]{9,10,12};
for (int a = 0; a< 3; a++)
{
c.gridx = gridX[a];
getContentPane().add(new JLabel(title[a]),c);
}
c.gridx = 11;
getContentPane().add(width,c);
c.gridx = 13;
getContentPane().add(height,c);
c.gridx = 11;
c.gridy = 0;
c.gridwidth = 2;
JButton button = new JButton("Done");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ButtonModel x = buttons.getSelection();
String size = "XXX";
System.out.println("Getting screen resolution");
int screenRes = Toolkit.getDefaultToolkit().getScreenResolution();
System.out.println("Successfully got screen resolution");
if (x!=null)
size = x.getActionCommand();
try{
TimeTable.width = new Integer(size)*screenRes;
TimeTable.height = (int)((TimeTable.titleCount+1)*inchesPerTimeline*screenRes);
}
catch(NumberFormatException ex)
{
try{
TimeTable.width = (int)(new Double(width.getText().trim())*screenRes);
TimeTable.height = (int)(new Double(height.getText().trim())*screenRes);
}
catch (NumberFormatException except)
{
return;
}
}
TimeTable.ready = true;
System.out.println("Size selected");
dispose();
}
});
getContentPane().add(button,c);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent winEvt){
System.exit(0);
}
});
setVisible(true);
}
}
Concise explanation :
I have a macro that runs out of Excel in Windows Vista and I tried to distribute it to a Computer running Windows 7. Upon execution the code failed to continue executing after this point i.e. it never printed out the words "Size selected". The rest of the program brings in a csv file from a C:\Users\?\AppData\TimeLineMacroProgram folder and later creates an image in the same directory. But this is the portion of the code that is currently broken. Whenever the GUI pops up I select the option for 9" and click done which should pass in 9 as a parameter and then print out "Size Selected" but it doesn't it only disposes the window. Please help.
Longshot guess:
There is an exit from your action listener if width and height text fields don't have content: you return after two NumberFormatExceptions. This would prevent "Size selected" from being displayed, and not dispose the frame. If you got the output "Successfully got screen resolution" and then it appeared to stop working, this could possibly be why. But if you experience that, and then click something else and then Done, it would print size selected.

Categories