java parsing data from component - java

I am creating a game, and I am doing a character selection screen which has a JTextField for entering the user name, the screen also has a JButton "Create Character", which, when pressed will parse the JTextField and if any problems(space in name, begin with space, etc..) it will put some text to a JLabel next to the JTextField.
I hook up the JButton to an actionPerformed method, which calls a function that parses the data. My problem is that every time I press the button, a new label is being placed on top of the original JLabel.
I create the JLabel like this:
public static JLabel label;
label = new JLabel();
// some properties
And I call the parsing method like so:
parseCharacterSelection(nameInput, label);
where nameInput is the JTextField.
My question is, why is there a new Label being created every time I press the JButton
public void parseCharacterCreation(JTextField input, JLabel label) {
// Variable that hold whether or not
// the User Name is acceptable
player_name = input.getText();
// Make some initial checks on the
// input string
//----------------------------------
if( player_name.isEmpty() ) {
label.setText("You need to pick a username");
} else if( player_name.startsWith(" ") ) {
label.setText("Name Cannot start with a space");
} else {
pass = true;
}
// Attempt to write to file
// Catch some errors
//----------------------------------
if(pass == true) {
try {
if( player_name.contains(" ") ) {
player_name = player_name.replaceAll("\\s", "_");
player_file = new File("src/Resources/characters/" + player_name + ".properties");
}
if(!player_file.exists()) {
player_file.createNewFile();
}
FileWriter fw = new FileWriter(player_file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(player_name);
bw.close();
} catch( IOException e ) {
e.printStackTrace();
} finally {
System.out.println("DONE");
}
}
}
// ScreenCharacter Class
public class ScreenCharacter extends JPanel {
public static JButton create;
public static JTextField nameInput;
public static JLabel errorLabel;
public ScreenCharacter() {
this.setLayout(null);
this.add(createUserName());
this.add(createMainArea());
}
private static JPanel createUserName() {
MatteBorder matteBorder = new MatteBorder(1, 0, 1, 0, Color.decode("#222222"));
EmptyBorder emptyBorder = new EmptyBorder(10, 75, 10, 10);
CompoundBorder border = new CompoundBorder(matteBorder, emptyBorder);
JPanel userNameArea = new JPanel();
userNameArea.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
userNameArea.setBounds(0, 35, Engine.screenX, 50);
userNameArea.setBorder(border);
userNameArea.setBackground(new Color(255, 255, 255, 70));
JLabel nameLabel = new JLabel();
nameLabel.setText("Enter Your Username: ");
nameInput = new JTextField();
nameInput.setForeground(Color.black);
nameInput.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));
nameInput.setPreferredSize(new Dimension(200, 25));
errorLabel = new JLabel();
errorLabel.setText("This is a test label");
errorLabel.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 0));
errorLabel.setPreferredSize(new Dimension(200, 25));
errorLabel.setAlignmentX(JLabel.LEFT_ALIGNMENT);
userNameArea.add(nameLabel);
userNameArea.add(nameInput);
userNameArea.add(errorLabel);
return userNameArea;
}
private static JPanel createMainArea() {
JPanel resetCreatePanel = new JPanel(new GridLayout(1, 2));
resetCreatePanel.setPreferredSize(new Dimension(300, 30));
resetCreatePanel.setBackground(Color.black);
create = new JButton("Create Character");
create.setBorder(BorderFactory.createLineBorder(Color.decode("#171717")));
create.setFont(new Font("Dialog", 1, 11));
create.setBackground(Color.black);
create.setForeground(Color.white);
create.setFocusPainted(false);
create.setContentAreaFilled(false);
create.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
if(!errorLabel.getText().isEmpty()) {
errorLabel.setText("");
} else {
Engine.p_parser.parseCharacterCreation(nameInput, errorLabel);
}
}
});
resetCreatePanel.add(create);
}
}
// Engine
public class Engine {
public static PlayerParser p_parser;
public Engine() {
p_parser = new PlayerParser();
}
}

Thanks everyone for the help. The "problem" was that the JPanel that the components were sitting on had a semi-transparent background. And JComponents with transparency get messed up somehow, which made it appear like there are multiple labels being created. But it works fine without transparency.

Related

How to calculate summation values from multiple JTextFields using loop in java

I am trying to making a calculator.
Here the user can add multiple JTextFields to take his/her desired input with just one button click.
Now I want that the user will take the input in multiple JTextFields added by him and on clicking the Result button will show the sum of all. But I am always getting 0 as output.
Code:
public class Button extends JFrame {
private JPanel contentPane;
private JButton btnAdd;
private JButton btnResult;
private JTextField resultField;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Button frame = new Button();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public Button() {
initComponents();
}
static JTextField field = null;
//static JTextField fields[] = new JTextField[10];
private static int y = 0;
ArrayList<String> arr = new ArrayList<String>();
int ans, sum = 0;
private void initComponents() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 527, 414);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
btnAdd = new JButton("Add");
btnAdd.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
field = new JTextField();
field.setBounds(45, y += 60, 284, 32);
field.setAlignmentX(Component.CENTER_ALIGNMENT);
contentPane.add(field);
contentPane.revalidate();
contentPane.repaint();
}
});
btnAdd.setBounds(170, 341, 89, 23);
contentPane.add(btnAdd);
btnResult = new JButton("Result");
btnResult.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < arr.size(); i++) {
arr.add(field.getText());
sum += Integer.parseInt(arr.get(i));
}
resultField.setText(String.valueOf(sum));
}
});
btnResult.setBounds(383, 306, 89, 23);
contentPane.add(btnResult);
resultField = new JTextField();
resultField.setBounds(361, 275, 129, 20);
contentPane.add(resultField);
resultField.setColumns(10);
}
}
Please help how can I find the correct output?
Suggestions:
Again, when you create a data-entry text field, add it to the GUI and add it to an ArrayList of the data entry field type.
Then in the result button's ActionListener, iterate through this list using a for loop.
Inside of the for loop, get the entry field, get its text (via .getText() if using a JTextField), parse it to number via Integer.parseInt(...), and add it to a sum variable that is initialized to 0 prior to the for loop. Then display the result after the loop.
Also,
Best to use JSpinners that use a SpinnerNumberModel such as JSpinner spinner = new JSpinner(new SpinnerNumberModel(0, 0, 1000, 1)); instead of JTextField for number entry. This will limit the user to entering numbers only, and won't allow non-numeric text entry, a danger inherent in your current design.
Having to add your entry fields by button may be an over-complication
But if it is necessary, then best to add the spinners (or text fields if you must) to a JPanel that uses a proper layout manager, such a new GridLayout(0, 1) (variable number of rows, 1 column) and then add that to a JScrollPane so that you can see as many fields as has been entered.
If using a JSpinner, then you don't even need a "calculate result" button, since if you add a ChangeListener to each JSpinner, you can calculate the result on the fly whenever a spinner has had its data changed.
e.g.,
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
#SuppressWarnings("serial")
public class Button2 extends JPanel {
private List<JSpinner> spinnerList = new ArrayList<>();
private JButton resultButton = new JButton("Result");
private JButton addEntryFieldBtn = new JButton("Add Entry Field");
private JTextField resultField = new JTextField(6);
private JPanel fieldPanel = new JPanel(new GridLayout(0, 1, 4, 4));
public Button2() {
resultField.setFocusable(false);
resultButton.addActionListener(e -> calcResult());
resultButton.setMnemonic(KeyEvent.VK_R);
addEntryFieldBtn.addActionListener(e -> addEntryField());
JPanel topPanel = new JPanel();
topPanel.add(addEntryFieldBtn);
topPanel.add(resultButton);
topPanel.add(new JLabel("Result:"));
topPanel.add(resultField);
JPanel centerPanel = new JPanel(new BorderLayout());
centerPanel.add(fieldPanel, BorderLayout.PAGE_START);
JScrollPane scrollPane = new JScrollPane(centerPanel);
scrollPane.setPreferredSize(new Dimension(300, 300));
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
setLayout(new BorderLayout());
add(topPanel, BorderLayout.PAGE_START);
add(scrollPane);
}
private void calcResult() {
int sum = 0;
for (JSpinner spinner : spinnerList) {
sum += (int) spinner.getValue();
}
resultField.setText(String.valueOf(sum));
}
private void addEntryField() {
JSpinner spinner = new JSpinner(new SpinnerNumberModel(0, 0, 1000, 1));
spinner.addChangeListener(evt -> {
calcResult();
});
fieldPanel.add(spinner);
spinnerList.add(spinner);
revalidate();
repaint();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
Button2 mainPanel = new Button2();
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}

Hangman adding pictures Swing

I am 'relatively' new to java creating a Hangman game in Java (Eclipse) using Swing. I have got all the components relating to the word done.
However I want that in the middle of the screen a Hangman image to be shown and when you get a guess wrong it updated with a different image (Of a more complete hangman).
However I am unsure of how to do this, whether I would need ImageIcon or just images and using paintComponent etc. Any Help appreciated, my code is below. I am unsure of how to do it in a efficient method that allows me to change it every time variable guess goes down. Please Suggest a method for doing this and the basics of how it might work.
public class Test extends JTextField {
private JFrame frame;
JTextField userInput;
private JTextField textField;
private String inputString;
private String total="";
private static char[] pass = Hangmangame.word.getPassword();
private static String passString = new String(pass);
private String []wordch = new String[passString.length()];
private String []astri = new String[passString.length()];
private int guess;
private boolean letter = false;
private JTextField txtGuesses;
private JPanel PicturePanel;
public static void start() {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Test window = new Test();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public Test() {
initialize();
}
public void initialize() {
for (int i = 0; i < passString.length(); i++) {
astri[i]="*";
wordch[i]=passString.substring(i, i+1);
total =total+ astri[i];
guess =10;
}
//------------------------------------------------
frame = new JFrame();
frame.setBounds(300, 100, 1000, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BorderLayout(0, 0));
//------------------------------------
JLabel Hangman = new JLabel("Hangman");
Hangman.setFont(new Font("Tahoma", Font.BOLD, 46));
Hangman.setHorizontalAlignment(SwingConstants.CENTER);
frame.getContentPane().add(Hangman, BorderLayout.NORTH);
//----------------------------------
textField = new JTextField(total);
textField.setBorder(null);
textField.setHorizontalAlignment(SwingConstants.CENTER);
textField.setFont(new Font("Tahoma", Font.BOLD, 46));
frame.getContentPane().add(textField, BorderLayout.SOUTH);
textField.setColumns(10);
//------------------------------------------
userInput = new JTextField();
userInput.setBorder(new LineBorder(new Color(0, 0, 0)));
userInput.setFont(new Font("Tahoma", Font.PLAIN, 22));
userInput.setHorizontalAlignment(SwingConstants.CENTER);
frame.getContentPane().add(userInput, BorderLayout.EAST);
userInput.setColumns(10);
TextFieldListener tfListener = new TextFieldListener();
userInput.addActionListener(tfListener);
//----------------------------------------------
txtGuesses = new JTextField();
txtGuesses.setBorder(null);
txtGuesses.setHorizontalAlignment(SwingConstants.LEFT);
txtGuesses.setFont(new Font("Tahoma", Font.BOLD, 20));
txtGuesses.setText("Guesses:"+guess);
frame.getContentPane().add(txtGuesses, BorderLayout.WEST);
txtGuesses.setColumns(10);
//-------------------------------
PicturePanel = new JPanel();
PicturePanel.setBackground(new Color(255, 255, 255));
frame.getContentPane().add(PicturePanel, BorderLayout.CENTER);
//----------------------------------------------
}
public class TextFieldListener implements ActionListener
{ public void actionPerformed(ActionEvent evt)
{ inputString = userInput.getText();
userInput.setText("");
checkcorrect();
}
}
private void checkcorrect() {
//runs it as many times as there are letters
for (int i = 0; i < passString.length(); i++) {
if(wordch[i].equals(inputString)) {
astri[i]=wordch[i];
total="";
// rewrites the *** with the letter added in same as code for setting up the astrixs.
for (int x = 0; x < passString.length(); x++) {
total =total+ astri[x];
}
textField.setText(total);
letter = true;
}
}
if(letter==true) {
letter=false;
}else {
guess=guess-1;
txtGuesses.setText("Guesses:"+guess);
if(guess==0) {
if(JOptionPane.showConfirmDialog(frame,"You Lose","Hangman",
JOptionPane.PLAIN_MESSAGE ) == JOptionPane.YES_OPTION ) {
System.exit(0);
}
}
}
if(total.equals(passString)) {
if(JOptionPane.showConfirmDialog(frame,"You Win","Hangman",
JOptionPane.PLAIN_MESSAGE ) == JOptionPane.YES_NO_OPTION ) {
System.exit(0);
}
}
}
private void Image() {
// My images
ImageIcon icon1 = new ImageIcon("P:\\Profiles\\workspace\\Games\\Images\\files\\0");
ImageIcon icon2 = new ImageIcon("P:\\Profiles\\workspace\\Games\\Images\\files\\1");
ImageIcon icon3 = new ImageIcon("P:\\Profiles\\workspace\\Games\\Images\\files\\2");
ImageIcon icon4 = new ImageIcon("P:\\Profiles\\workspace\\Games\\Images\\files\\3");
ImageIcon icon5 = new ImageIcon("P:\\Profiles\\workspace\\Games\\Images\\files\\4");
ImageIcon icon6 = new ImageIcon("P:\\Profiles\\workspace\\Games\\Images\\files\\5");
ImageIcon icon7 = new ImageIcon("P:\\Profiles\\workspace\\Games\\Images\\files\\6");
ImageIcon icon8 = new ImageIcon("P:\\Profiles\\workspace\\Games\\Images\\files\\7");
ImageIcon icon9 = new ImageIcon("P:\\Profiles\\workspace\\Games\\Images\\files\\8");
ImageIcon icon10 = new ImageIcon("P:\\Profiles\\workspace\\Games\\Images\\files\\9");
ImageIcon icon11 = new ImageIcon("P:\\Profiles\\workspace\\Games\\Images\\files\\10");
}
}

JComboBox Index just returns 0 upon request

Im just working on a JFrame.I added a JComboBox there but unfortunately the JComboBox Index, and so the selected Item doesn't change upon "the action of changing", I mean when I select another Item on the Swing Frame. When requested, it only returns an Index of 0, no matter what Item is selected. The name of the ComboBox is "Kataloge".
It does not return me any Error.
How can I fix this ?
static BufferedImage icon;
private JButton update;
private JButton getKata;
private JComboBox<String> Kataloge;
private JLabel Title;
private JLabel WhichKatalog;
private JLabel WhichDatum;
private JLabel line;
private JPanel topper;
private JPanel middle;
private JPanel bottom;
private JPanel frame;
public String Katalog = "Fragenkatalog 1 (normiert)";
public static void main(String args[]) {
MainFrame frame = new MainFrame();
frame.draw();
}
public MainFrame(){
setTitle("Fragebogen erstellen Section");
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {
}
draw();
setResizable(false);
try {
icon = ImageIO.read(new File("icon.png"));
} catch (IOException e) {
e.printStackTrace();
}
setIconImage(icon);
setVisible(true);
}
public void draw(){
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
update = new JButton();
getKata = new JButton();
Title = new JLabel();
line = new JLabel();
WhichKatalog = new JLabel();
WhichDatum = new JLabel();
topper = new JPanel();
middle = new JPanel();
bottom = new JPanel();
frame = new JPanel();
setSize(575, 220);
getKata.setFont(new java.awt.Font("Tahoma", 0, 14));
getKata.setText("Fragebogen erstellen");
getKata.addActionListener(new ActionHandler());
update.setFont(new java.awt.Font("Tahoma", 0, 14));
update.setText("Katalog bearbeiten");
update.addActionListener(new ActionHandler());
Kataloge = new JComboBox<String>();
Kataloge.addItem("Fragenkatalog 1 (normiert)");
Kataloge.addItem("Fragenkatalog 2 (normal)");
Kataloge.setFont(new java.awt.Font("Tahoma", 0, 14));
Kataloge.addItemListener(new ItemHandlerMainFrame());
Title.setFont(new java.awt.Font("Tahoma", 1, 24)); // NOI18N
Title.setText("Main Menu");
WhichKatalog.setText("Ausgewählter Katalog: "+Katalog);
WhichDatum.setText(new Datum().getDatum());
line.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
frame.setSize(575, 220);
topper.setSize(575,40);
topper.setLayout(new FlowLayout());
topper.add(Title, CENTER_ALIGNMENT);
middle.setSize(575, 150);
middle.setLayout(null);
middle.add(getKata).setBounds(15, 30, 160, 30);;
middle.add(update).setBounds(195,30,145,30);;
middle.add(Kataloge).setBounds(360, 30, 200, 30);;
bottom.setSize(575,30);
bottom.setLayout(new BorderLayout(50,5));
bottom.add(line, BorderLayout.NORTH);
bottom.add(WhichKatalog, BorderLayout.WEST);
bottom.add(WhichDatum, BorderLayout.EAST);
frame.setLayout(null);
frame.add(topper).setBounds(0, 10, 575, 40);;
frame.add(middle).setBounds(0,45,575,60);;
frame.add(bottom).setBounds(15, 150, 535, 30);;
getContentPane().add(frame);
setLocationRelativeTo(null);
setLocationRelativeTo(null);
}
public void close(){
this.setVisible(false);
this.dispose();
}
private class ActionHandler implements ActionListener{
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand()=="Fragebogen erstellen"){
close();
FragebogenErstellen frame = new FragebogenErstellen();
frame.drawIt();
}
}
}
private class ItemHandlerMainFrame implements ItemListener{
public void itemStateChanged(ItemEvent e) {
if(e.getStateChange() == ItemEvent.SELECTED){
System.out.println("Changed to: "+Kataloge.getSelectedIndex());
}
//Katalog = (String) Kataloge.getSelectedItem();
if (Katalog == "Fragenkatalog 1 (normiert)"){
WhichKatalog.setText("Ausgewählter Katalog: "+Katalog);
}if (Katalog == "Fragenkatalog 2 (normal)"){
WhichKatalog.setText("Ausgewählter Katalog: "+Katalog+" ");
}
}
}
You're calling draw twice, which is going to cause no end of issue as it's re-creating many of you objects.
Basically what's happening, is your double layering your components, you actually have two JComboBoxs on the screen, one you interact with and one which you can't. In your case, it's actually the one you can't interact with which was created last, it's returning 0 constantly when you call getSelectedIndex, because that's what's selected
In this case, there's no reason for draw to be public, in fact, for the most part, it could just be part of classes constructor
e.getActionCommand()=="Fragebogen erstellen" is not how Strings are compared in Java, you should be using String#equals
Avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify

how do i create a virtual keyboard that can be used to insert values in different jtextfields

So I am trying to create a virtual keyboard that can insert values in a Jtextfield of another Jframe. The problem is that the data is overlapping when editing other text fields. So, I tried renewing the object but it replaced the first Jtextfield value as well. what should i do with this, should i start from scratch or is there any other way? . Since, English is not my first language I am struggling to find the correct terminology to research the problem please enlighten me with your knowledge
import java.awt.*;
import javax.swing.*;
public class OnScreenKeyboard implements ActionListener {
JFrame keyboard;
static String keyboardKeys = "0123456789qwertyuiopasdfghjklzxcvbnm.< ";
JButton[] keys = new JButton[39];
GridLayout gl;
FlowLayout fl;
Dimension buttondimension;
JPanel panel1, panel2;
JToggleButton capslock;
private String message = "";
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public OnScreenKeyboard() {
buttondimension = new Dimension(45, 40);
fl = new FlowLayout();
capslock = new JToggleButton("capslock");
panel1 = new JPanel(fl);
panel2 = new JPanel(fl);
char[] key = keyboardKeys.toCharArray();
for (int i = 0; i < 39; i++) {
keys[i] = new JButton(String.valueOf(key[i]));
keys[i].setFont(new Font("Arial", Font.PLAIN, 13));
if (i == 38) {
keys[i].setPreferredSize(new Dimension(100, 30));
} else {
keys[i].setPreferredSize(buttondimension);
}
keys[i].addActionListener(this);
}
keyboard = new JFrame("Keyboard");
keyboard.setSize(720, 220);
keyboard.setLocationRelativeTo(null);
keyboard.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
keyboard.setResizable(false);
Container content = keyboard.getContentPane();
content.setLayout(null);
panel1.setBounds(1, 1, 500, 210);
panel2.setBounds(510, 1, 200, 210);
for (int i = 0; i < 10; i++) {
panel2.add(keys[i]);
}
for (int i = 10; i < 39; i++) {
panel1.add(keys[i]);
}
panel1.add(capslock);
content.add(panel1);
content.add(panel2);
capslock.addActionListener(this);
keyboard.setVisible(true);
}
public static void main(String[] args) {
new OnScreenKeyboard();
}
public void reset(){
message = "";
}
#Override
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < 36; i++) {
if (e.getSource() == keys[i]) {
setMessage(getMessage() + keys[i].getText());
break;
}
}
if (e.getSource() == capslock) {
if (capslock.isSelected()) {
for (int i = 10; i < 36; i++) {
keys[i].setFont(new Font("Arial", Font.PLAIN, 12));
keys[i].setText(keys[i].getText().toUpperCase());
}
} else if (!capslock.isSelected()) {
for (int i = 10; i < 36; i++) {
keys[i].setFont(new Font("Arial", Font.PLAIN, 13));
keys[i].setText(keys[i].getText().toLowerCase());
}
}
}
setMessage(getMessage());
//JOptionPane.showMessageDialog(null, getMessage());
}
}
this is the frame I am trying to put my values from the keyboard in
public class LoginScreen implements ActionListener, FocusListener {
JFrame frame;
Container content;
FlowLayout fl;
JTextField txtusername, txtpassword;
JLabel lblusername, lblpassword;
JPanel panel1, panel2;
JButton keyboard, signup, signin;
OnScreenKeyboard kyb;
Dimension text;
private void init() {
text =new Dimension(100, 30);
fl = new FlowLayout(FlowLayout.CENTER);
lblusername = new JLabel("enter username");
lblpassword = new JLabel("enter password");
txtusername = new JTextField();
txtpassword = new JPasswordField();
keyboard = new JButton("keyboard");
signup = new JButton("signup");
signin = new JButton("sign in");
panel1 = new JPanel(fl);
panel2 = new JPanel(fl);
keyboard = new JButton("keyboard");
txtusername.setPreferredSize(text);
txtpassword.setPreferredSize(text);
kyb = new OnScreenKeyboard();
}
public LoginScreen() {
init();
frame = new JFrame("BorderLayoutDemo");
frame.setTitle("Registration Form");
frame.setSize(300, 300);
frame.setDefaultCloseOperation(3);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
content = frame.getContentPane();
content.setLayout(new GridLayout(2, 1));
panel1.add(lblusername);
panel1.add(txtusername);
panel1.add(lblpassword);
panel1.add(txtpassword);
panel2.add(signup);
panel2.add(signin);
panel2.add(keyboard);
content.add(panel1);
content.add(panel2);
keyboard.addActionListener(this);
txtusername.addFocusListener(this);
txtpassword.addFocusListener(this);
}
public static void main(String[] args) {
new LoginScreen();
}
#Override
public void actionPerformed(ActionEvent e) {
if (!kyb.keyboard.isVisible()) {
if (e.getSource() == keyboard) {
kyb = new OnScreenKeyboard();
}
}
}
#Override
public void focusGained(FocusEvent e) {
if(txtusername == e.getSource()){
txtusername.setText(kyb.getMessage());
}else if(txtpassword == e.getSource()){
kyb.reset();
txtpassword.setText(kyb.getMessage());
}
}
#Override
public void focusLost(FocusEvent e) {
}
The problem is that it's weird how/when the text is taken from the keyboard.
You use the LoginScreen both as actionListener on the keyboard and as focusListener on the 2 textfields.
The way you implemented it now is that you "type" something in on the keyboard and after that put the focus on 1 of the 2 fields. Only at the moment you click the text from the keyboard is fetched (kyb.getMessage()).
It's especially a problem on the password. If you click on the txtpassword field you first reset the kyb and then fetch the message (which you just reset so is empty).
What felt weird for me is that you don't have a way in the keyboard to notion that you are done typing. So the flow of only getting the message when the focus changes to one of the text fields is wrong.
What I would do is create a new kind of KeyboardListener. This listener is put on the txtusername OR txtpassword depending on who last took focus (so in the focusGained() you should change who is listening to the keyboard).
Then each time a key is "typed" you should notify the listener of the letter and then the txtusername/txtpassword (whichever is listening at that time) should add that letter to its text.
This means that the keyboard itself doesn't need to remember any text. It just figures out which key was pressed and then sends the corresponding letter to the listener.
You should be using a TextAction as your ActionListener. The TextAction has a method getFocusedComponent() which will return the last text component to have focus.
Then in the can add the character to the text field. So the basic code in the actionPerformed(...) method of the TextAction might be something like:
JTextComponent component = getFocusedComponent();
component.replaceSelection( the character to add );

JButtons Wont Display?

I'm sorry for posting this but, I can't find out why my Array of JButtons won't display in my ButtonsPanel. After adding them, I tried using my code in a separate class to test my code and it worked!, but why don't my buttons show up in this class?
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.border.LineBorder;
public class WordGui extends JFrame {
private JPanel contentPane;
private JTextField textField;
private JLabel lblNewLabel_1;
private JPanel buttonPanel;
private JTextArea txtrShuffleHistory;
private Word word ;
private boolean val;
private JButton btnGo;
private JButton button;
private JButton btnShuffleText;
private JPanel panel_1;
/**
* Launch the application.
*/
public static void main(String[] args) {
try {
com.jtattoo.plaf.noire.NoireLookAndFeel.setTheme("Small-Font","","05:Bageo,Dexter");
UIManager.setLookAndFeel("com.jtattoo.plaf.noire.NoireLookAndFeel");
} catch (Throwable e) {
e.printStackTrace();
}
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
WordGui frame = new WordGui();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public WordGui() {
setTitle("Word App Gui");
setResizable(false);
setBounds(new Rectangle(100, 100, 600, 200));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 719, 394);
contentPane = new JPanel();
contentPane.setBounds(new Rectangle(100, 100, 600, 200));
contentPane.setSize(new Dimension(600, 250));
contentPane.setPreferredSize(new Dimension(600, 250));
contentPane.setBorder(new LineBorder(new Color(204, 0, 255), 5, true));
setContentPane(contentPane);
contentPane.setLayout(null);
JPanel panel = new JPanel();
panel.setBorder(new LineBorder(new Color(204, 0, 255), 3, true));
panel.setBounds(10, 11, 683, 45);
contentPane.add(panel);
panel_1 = new JPanel();
panel_1.setBorder(new LineBorder(new Color(204, 0, 255), 3, true));
panel_1.setBounds(140, 59, 553, 286);
contentPane.add(panel_1);
panel_1.setLayout(null);
JLabel lblNewLabel = new JLabel("Enter a new word here:");
lblNewLabel.setBounds(10, 11, 183, 14);
panel_1.add(lblNewLabel);
textField = new JTextField();
textField.setBounds(224, 8, 157, 20);
panel_1.add(textField);
textField.setColumns(10);
btnGo = new JButton("Go");
btnGo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
if(ev.getSource()== btnGo){
assignWord(textField.getText());
}
}
});
btnGo.setBounds(391, 7, 57, 23);
panel_1.add(btnGo);
JLabel lblOriginalText = new JLabel("Original Text:");
lblOriginalText.setBounds(10, 36, 84, 14);
panel_1.add(lblOriginalText);
lblNewLabel_1 = new JLabel("New label");
lblNewLabel_1.setToolTipText("This is the original text entered\r\n");
lblNewLabel_1.setHorizontalTextPosition(SwingConstants.CENTER);
lblNewLabel_1.setHorizontalAlignment(SwingConstants.CENTER);
lblNewLabel_1.setBorder(new LineBorder(new Color(204, 0, 255), 3, true));
lblNewLabel_1.setBounds(90, 36, 358, 79);
panel_1.add(lblNewLabel_1);
JLabel lblShuffledText = new JLabel("Shuffled Text:");
lblShuffledText.setBounds(10, 126, 110, 14);
panel_1.add(lblShuffledText);
buttonPanel = new JPanel();
buttonPanel.setBorder(new LineBorder(new Color(204, 0, 255), 4, true));
buttonPanel.setBounds(10, 147, 533, 56);
panel_1.add(buttonPanel);
buttonPanel.setLayout(new GridLayout(1, 0, 0, 0));
btnShuffleText = new JButton("Shuffle Text");
btnShuffleText.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
if(ev.getSource() == btnShuffleText){
shuffle();
}
}
});
btnShuffleText.setBounds(90, 214, 196, 39);
panel_1.add(btnShuffleText);
button = new JButton("Reset");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
if(ev.getSource() == button){
textField.setText("");
getGoBtn().setEnabled(true);
getShuffleBtn().setEnabled(false);
getButtonPanel().removeAll();
}
}
});
button.setBounds(294, 214, 196, 39);
panel_1.add(button);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setBounds(10, 59, 128, 258);
contentPane.add(scrollPane);
txtrShuffleHistory = new JTextArea();
txtrShuffleHistory.setToolTipText("View Shuffle History");
txtrShuffleHistory.setText("Shuffle History\r\n=================");
txtrShuffleHistory.setEditable(false);
scrollPane.setViewportView(txtrShuffleHistory);
JButton btnClear = new JButton("Clear");
btnClear.setBounds(10, 322, 126, 23);
contentPane.add(btnClear);
valid();
}
public void valid(){
JTextField field = new JTextField();
while(val == false){
int result = JOptionPane.showConfirmDialog(null,field, "Enter a Text?", JOptionPane.OK_CANCEL_OPTION);
if(result == JOptionPane.OK_OPTION){
String s = field.getText();
assignWord(s);
}
else if(result == JOptionPane.CANCEL_OPTION){
getResetBtn().setEnabled(false);
getShuffleBtn().setEnabled(false);
val = true;
}
}
}
public void assignWord(String s){
try{word = new Word(s);
val = true;
getTextLabel().setText("<html><body><font size = 30 >"+s+"</font></body></html>");
getTextArea().append("\nOriginal Word :"+s+"\n=================");
getGoBtn().setEnabled(false);
getResetBtn().setEnabled(true);
getShuffleBtn().setEnabled(true);
}
catch(RuntimeException e){JOptionPane.showMessageDialog(getParent(),e.getMessage()); val = false;}
}
public void shuffle(){
word.shuffle();
getButtonPanel().removeAll();
String temp = word.getShuffledText();
JButton[] buttons = new JButton[word.getText().length()];
for(int x = 0; x < word.getShuffledText().length(); x++){
buttons[x] = new JButton(""+temp.charAt(x));
getBody().add(buttons[x]);
buttons[x].setVisible(true);
}
getTextArea().append("\n"+word.getShuffledText());
}
public JLabel getTextLabel() {
return lblNewLabel_1;
}
public JPanel getButtonPanel() {
return buttonPanel;
}
public JTextArea getTextArea() {
return txtrShuffleHistory;
}
public JTextField getTextField() {
return textField;
}
public JButton getGoBtn() {
return btnGo;
}
public JButton getResetBtn() {
return button;
}
public JButton getShuffleBtn() {
return btnShuffleText;
}
public JPanel getBody() {
return panel_1;
}
}
I have the shuffle method which does the adding of JButtons, I'm sorry for posting this long long code, but can somebody compile this and figure out why the buttons wont show ? I tried changing the panels layout but still doesn't work,
here's the supporting class
import java.util.*;
public class Word {
private String text;
private List<Character> charList;
private String shuffled;
public Word(String str) {
if (str.length() < 3) {
throw new RuntimeException("Word must be more than 2 characters...");
}
if(invalid(str)) {
throw new RuntimeException("Word must not be composed of a single character...");
}
text = str.toUpperCase();
charList = getChars();
shuffle();
}
private boolean invalid(String s) {
int count = 1;
for (int i = 1; i < s.length(); i++) {
if (Character.toLowerCase(s.charAt(0)) == Character.toLowerCase(s.charAt(i)))
count++;
}
return (count == s.length());
}
private ArrayList<Character> getChars() {
ArrayList<Character> tempList = new ArrayList<Character>();
for (int i = 0; i < text.length(); i++) {
tempList.add(text.charAt(i));
}
return tempList;
}
public void shuffle() {
String orig = shuffled;
String tempShuffled;
do {
Collections.shuffle(charList);
tempShuffled = listToString();
} while (tempShuffled.equals(orig) || tempShuffled.equals(text));
shuffled = tempShuffled;
}
private String listToString() {
String strTemp = "";
for (Character ch: charList) {
strTemp += ch;
}
return strTemp;
}
public String toString() {
return text;
}
public String getShuffledText() {
return shuffled;
}
public String getText(){
return text;
}
}
You're using absolute positioning (null layout) for the JPanel panel_1. Each component in the JButton array buttons will have a default size of 0 x 0 so will not appear.
Swing was designed to use a layout manager so its recommended to always use one.
It removes the need to set component dimensions and locations. Use one for panel_1, such as GridLayout.
Also invoke
panel_1.revalidate();
panel_1.repaint();
after adding all of the buttons from the array.
Aside: Java naming conventions show that variables use camelCase such as panelOne instead of panel_1.
panel_1.setLayout(null);
Here, you're basically left with absolute positioning, so you'll need to set size and position for each of your JButtons. Use setBounds

Categories