How to change my grid size (using JTextField) - java

So I have bunch of grids on my window and I have a JTextField, I want to write a number, say
20, in the text field and the 20 would change my grid size to 20 and so on.
Here you see I have set it to 30, I can set it to any number, but like I said I want to be
able to change/set the number when I type it in the text field after I run the program.
This is my Grids class and not the main class, In my main class I created the text field and
such. Also I have my actionPreformed in my main so what do I need in my actionPreformed
(if necessary)?
So my question is after running the program how to write in the text field a
number (10,20,30 any number) and be able to change my grid size based on the number I typed?
Also what do I need in my actionPreformed (if necessary)?
Grids class:
protected int gridSize = 30; // how many grids
public Grids( ghetto ttt )
{
setLayout( new GridLayout( gridSize, gridSize ) );
theSquares = new Marker[gridSize][gridSize];
for ( int i=0; i<gridSize; i++ )
{
for ( int j=0; j<gridSize; j++ )
{
theSquares[i][j] = new Marker(gridSize , this );
add(theSquares[i][j]);
}
}
}

I would use a JSpinner with a ChangeListener.
Read the section from the Swing tutorial on How to Use Spinners for more information and examples.

So an actionlistener probably won't work. That condenses click events into ActionEvents. What you can do is add a document listener. See Value Change Listener to JTextField.
In your main program where you would do
textField.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
// Whatever
}
});
you do
textField.getDocument().addDocumentListener(new DocumentListener() {
#Override
public void removeUpdate(DocumentEvent arg0) {
//whatever
}
#Override
public void insertUpdate(DocumentEvent arg0) {
//whatever
}
#Override
public void changedUpdate(DocumentEvent arg0) {
//whatever
}
});

Related

how to get mouse pointer component in swing application

my swing application one panel have 6 button. when cursor goes on the button i want to change default cursor to hand cursor and cursor is exit then it want to change default cursor. Now i am doing this thing using below code.
private void btnRegisterReceiptMouseEntered(java.awt.event.MouseEvent evt) {
btnRegisterReceipt.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
private void btnRegisterReceiptMouseExited(java.awt.event.MouseEvent evt) {
btnRegisterReceipt.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
Now i want to write this code to each and every button.
But I want to write common method to do this one. I already try to use MouseListener do this thing, but I can not get which is the mouse point component.
I don't know it is possible or not. if it is possible please anyone tell me how to do this things.
private void changeCursor() {
addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered( MouseEvent e ) {
/*if ( mouse Entered compornent is button ) {
button.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
} else {
button.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}*/
}
});
}
Write a generic MouseListener (as an annonymouse class):
MouseListener ml = new MouseAdapter()
{
#Override
public void mouseEntered(MouseEvent e)
{
e.getComponent( setCursor(...) );
}
#Override
public void mouseExited(MouseEvent e)
{
e.getComponent( setCursor(...) );
}
};
Then you can just add the MouseListener to any component you want with:
btnRegisterReceipt.addMouseListener( ml );
anotherButton.addMouseListener( ml );
You can also make this as a reusable class:
public MousePointerListener extends MouseAdapter
{
#Override
public void mouseEntered(MouseEvent e)
{
e.getComponent( setCursor(...) );
}
#Override
public void mouseExited(MouseEvent e)
{
e.getComponent( setCursor(...) );
}
}
Then you use:
MouseListener ml = new MousePointerListener();
btnRegisterReceipt.addMouseListener( ml );
anotherButton.addMouseListener( ml );
The key point in both examples is that you can get the source of the event from the MouseEvent, which allows you to write generic code. You should look at this approach for all you listeners, instead of letting your IDE generate the listener code.

Disable button in Java until all fields filled

I'm new to Java and developing a small project. I'm making a program where the user has to register themselves. I have 3 different tabs on my Tabbed Pane. I want to be able to disable the next button on the first pane making it impossible for the user to continue to pane 2 unless all the text fields on pane 1 have been filled. I have been Searching online and found various examples but none of them would work in run time.
I am using Netbeans.
private void txtFirstNameActionPerformed(java.awt.event.ActionEvent evt) {
if(txtFirstName.getText().trim().length() > 0)
btnNext1.setEnabled(true);
else
btnNext1.setEnabled(false);
}
Create a List of all the text fields on your pane:
List<JTextField> list = new ArrayList<>();
Add all your text fields to that list.
Then, create a universal DocumentListener that listens for text change events, and every time a text update happens, scan through all your text fields to see if they have all been filled:
DocumentListener listener = new DocumentListener() {
#Override
public void removeUpdate(DocumentEvent e) { changedUpdate(e); }
#Override
public void insertUpdate(DocumentEvent e) { changedUpdate(e); }
#Override
public void changedUpdate(DocumentEvent e) {
boolean canEnable = true;
for (JTextField tf : list) {
if (tf.getText().isEmpty()) {
canEnable = false;
}
}
btnNext1.setEnabled(canEnable);
}
};
And add that listener to every text field you have in the list:
for (JTextField tf : list) {
tf.getDocument().addDocumentListener(piecesListener);
}

How to remove object (including components) from arraylist?

I'm working on a task planning app. I have a 'new task' button to add a task. When clicked, this button makes a new instance of the TaskRowToDo class and adds this to the toDoList arraylist. This class contains a row with a text field and some buttons.
This is the 'new task' button code:
private void drawNewBtn(){
JButton btnNew = new JButton("Nieuwe taak");
btnNew.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("New task added");
toDoList.add(new TaskRowToDo(toDoIndex+7, false, "new task", 2));
toDoList.get(toDoIndex).draw();
toDoIndex++;
frmPlanner.revalidate();
}
});
frmPlanner.getContentPane().add(btnNew, "cell 3 12");
}
At the end of the TaskRowToDo there is a 'remove' button. This button should remove the row from the toDoList and remove this row from the screen.
Below is the 'remove' button code:
btnRemoveToDo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("To Do removed");
toDoIndex--;
toDoList.remove(toDoIndex);
frmPlanner.revalidate();
}
});
The button removes the instance of TaskRowToDo from the toDoList, but it still shows up on screen and the components even work. So it's not really removed. I've tried using revalidate() and repaint() but to no avail. As a test I tried frmPlanner.removeAll() and even this doesn't clear the screen (however the components won't work anymore).
How do I remove this one row, including its components and clear this space on the screen?
toDoList is JList?
give same more code, on this time I suggest to setModel on JList.
I always prepare method setModel when I create JList and it works:
private void setModelForJList() {
toDoList.setModel(new ListModel<TaskRowToDo>() {
#Override
public int getSize() {
return toDoListEntityList.size();
}
#Override
public TaskRowToDogetElementAt(int index) {
return toDoListEntityList.get(index);
}
#Override
public void removeListDataListener(ListDataListener l) {
}
#Override
public void addListDataListener(ListDataListener l) {
}
});
toDoList.repaint();
}
when you delete object from JList, call this method, toDoListEntityList is list of object which you put in Jlist.
About JList some advices. Good practice is declare generic type of JList (in your case is JList<TaskRowToDo> toDoList= new JList<TaskRowToDo>

Can't get two pictures to "move" at the same time with simultaneous keystrokes using previous answers

In this code I have a graphic (paintcomponent graphic) that has two tanks. The paintcomponent is controlled by variables and then a repaint(). Right now, it works perfectly when only one button is being pressed or held down. However, if I hold the left for tank1 and the right for tank2, for example, the last-most key is the one that "wins": It is the only direction that occurs.
In my code you will find about 4 of my latest attempts kind of ‘iteratingly’ added to the code.
The basic setup is: Keybinding→AbstractAction→...
The setup above without ellipses(…) represents the original attempt. Then, in another attempt, this is chained to a thread. Same result. In another attempt the abstract action is set to change an array value, which is connected to a timer that checks every 20 seconds. The two attempts branching from there is the connection of the timer to the thread, and the directly repaint put in the timer.
My only other option at this point is to make separate key bindings for each combination (i.e., holding left and D [D moves tank1] would be a keybinding with the keycode "LEFT D" and thus would be a separate event that moved both). However, this would be a hassle because I also have turrets that change angles, and bullets that fire… Also I'd like to think there's a more decent way to do this.
Any help will be appreciated. The code is below.
class OneMoveRightThread implements Runnable { //This is a thread that contains code to 'move' the tank1.
public void run(){
tankGraphic.TankOneMoveRight();
gameArea.repaint();
}
}
class OneMoveLeftThread implements Runnable { //thread to move tank2
public void run(){
tankGraphic.TankOneMoveLeft();
gameArea.repaint();
}
}
//Meow is a [0,0,0,0,0,0,0,0] (8 zeroes) array. When a button is clicked the value is set to 1 for the spot in the array.
ActionListener taskPerformer = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (meow[0] == 1){ //This attempt uses a timer to constantly check the array for potential movement. Still works for 1 movement at a time.
(new Thread(new OneMoveLeftThread())).start();
meow[0]=0;
}
if(meow[1]==1){
(new Thread(new OneMoveRightThread())).start(); //using code in threads by calling the thread. My hope was that this would fix it.
meow[1]=0;
}
if (meow[2]==1){ //TANK TWO MOVE LEFT using code in threads
tankGraphic.TankTwoMoveLeft();
gameArea.repaint();
meow[2]=0;
}
}
};
new Timer(delay, taskPerformer).start();
//This abstract action is a different part of the code.
Action doNothing = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
lifeBar1.setText("\n Player 1: " + player1Name + " \n Health: " + player1Health + " \n Bullets: A LOT!");
lifeBar2.setText("\n Player 2: " + player2Name + " \n Health: " + player2Health + " \n Bullets: A LOT!");
}
};
//TANK TWO BELOW
Action leftMove = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) { //This is code for "When LEFT arrow is pressed, set meow[2]=1"
//tankGraphic.TankTwoMoveLeft();
//gameArea.repaint();
meow[2]=1;
}
};
Action rightMove = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) { //This is code for when RIGHT arrow is pressed, move tank directly. This and the above have same erroneous result.
tankGraphic.TankTwoMoveRight();
gameArea.repaint();
}
};
Action angleLEFT = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
tankGraphic.TankTwoAngleLeft();
gameArea.repaint();
}
};
Action angleRIGHT = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
tankGraphic.TankTwoAngleRight();
gameArea.repaint();
}
};
//TANK ONE BELOW
Action leftMove2 = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
meow[0]=1;
}
};
Action rightMove2 = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
//(new Thread(new OneMoveRightThread())).start();
meow[1]=1;
}
};
Action angleLEFT2 = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
tankGraphic.TankOneAngleLeft();
gameArea.repaint();
}
};
Action angleRIGHT2 = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
tankGraphic.TankOneAngleRight();
gameArea.repaint();
}
};
//these two lines are irrelevant. They match the irrelevant abstractaction.
gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("B"), "doNothing");
gameArea.getActionMap().put("doNothing",doNothing);
//below is the code for the keybindings.
//the names are reversed, below. (fire1 corresponds to tank two, but the right side of the keyboard)
gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("LEFT"), "leftMove");
gameArea.getActionMap().put("leftMove",leftMove);
gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("RIGHT"), "rightMove");
gameArea.getActionMap().put("rightMove",rightMove);
gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("UP"), "angleLEFT");
gameArea.getActionMap().put("angleLEFT",angleLEFT);
gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("DOWN"), "angleRIGHT");
gameArea.getActionMap().put("angleRIGHT",angleRIGHT);
gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("A"), "leftMove2");
gameArea.getActionMap().put("leftMove2",leftMove2);
gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("D"), "rightMove2");
gameArea.getActionMap().put("rightMove2",rightMove2);
gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("W"), "angleLEFT2");
gameArea.getActionMap().put("angleLEFT2",angleLEFT2);
gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("S"), "angleRIGHT2");
gameArea.getActionMap().put("angleRIGHT2",angleRIGHT2);
//gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("E"), "fire2");
//gameArea.getActionMap().put("fire2",fire2);
//gameArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("SLASH"), "fire1");
//gameArea.getActionMap().put("fire1",fire1);
frame.requestFocus();
Take a look at Motion Using the Keyboard.
The KeyboardAnimation.java example does this. The class shows one way to add animation using Key Bindings and a Swing Timer. Each key binding can control a different image and a different Timer.
One image is controlled by the 4 arrow keys and the other by the "a, d, w, s" keys.

How to make a String not-deletable in JTextarea?

Basically, I have a dropdown menu containing templates. For example:
apple( )
banana( )
Once one of them is selected, it pastes onto a JTextArea. My problem is if "apple( )" is selected, I want "apple" and the two brackets non-deletable in the TextArea, and user can enter anything inside the brackets.
Can anyone give me any direction/ideas here? I have been searching on the internet and found very little about this.
Check out the Proctected Text Component. It allows you to mark individual pieces of text as protected so that it can't be changed or deleted.
It uses a DocumentFilter as well as a NavigationFilter.
For a simpler solution you might be able to just use a NavigationFilter. The example below shows how you can prevent the selection of text at the beginning of the Document. You should be able to customize it to also prevent selection of text at the end of the document as well.
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
public class NavigationFilterPrefixWithBackspace extends NavigationFilter
{
private int prefixLength;
private Action deletePrevious;
public NavigationFilterPrefixWithBackspace(int prefixLength, JTextComponent component)
{
this.prefixLength = prefixLength;
deletePrevious = component.getActionMap().get("delete-previous");
component.getActionMap().put("delete-previous", new BackspaceAction());
component.setCaretPosition(prefixLength);
}
#Override
public void setDot(NavigationFilter.FilterBypass fb, int dot, Position.Bias bias)
{
fb.setDot(Math.max(dot, prefixLength), bias);
}
#Override
public void moveDot(NavigationFilter.FilterBypass fb, int dot, Position.Bias bias)
{
fb.moveDot(Math.max(dot, prefixLength), bias);
}
class BackspaceAction extends AbstractAction
{
#Override
public void actionPerformed(ActionEvent e)
{
JTextComponent component = (JTextComponent)e.getSource();
if (component.getCaretPosition() > prefixLength)
{
deletePrevious.actionPerformed( null );
}
}
}
private static void createAndShowUI()
{
JTextField textField = new JTextField("Prefix_", 20);
textField.setNavigationFilter( new NavigationFilterPrefixWithBackspace(7, textField) );
JFrame frame = new JFrame("Navigation Filter Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(textField);
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
You'll have to do this yourself. I'd suggest you to make an event handler that fires every time the text changes (Click here to find out how). And inside that handler check if the JTextArea still starts with "apple(" and ends with ")".

Categories