I have a grid layout that is 9x9 and generates Jtextareas to fill it. If the user presses a button i want the grid layout to become empty again so i can refill it again but with no relation to what it previously was filled with.
is there some sort of command like gridlayout.delete() or something?
I'm guessing that you want to clear the text components that are held by the GridLayout-using container (you don't tell us, and please understand that this is key information about your question). If so, put them into a collection such as an ArrayList and iterate through the list calling setText("") within the loop.
If you're using Java 8, then this "for loop" can be replaced with a forEach(...) call on a Stream. For example, if you have an ArrayList like so:
List<JTextComponent> textComponentList = new ArrayList<>();
Then you can clear all the text components it holds with this call:
textComponentList.stream().forEach(tc -> tc.setText(""));
For example:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import javax.swing.text.JTextComponent;
#SuppressWarnings("serial")
public class ClearGrid extends JPanel {
private static final int ROWS = 9;
private static final int COLS = ROWS;
private static final int GAP = 2;
private static final Font FONT = new Font(Font.SANS_SERIF, Font.BOLD, 32);
private static final int FIELD_COLS = 2;
List<JTextComponent> textComponentList = new ArrayList<>();
public ClearGrid() {
JPanel gridPanel = new JPanel(new GridLayout(ROWS, COLS, GAP, GAP));
gridPanel.setBackground(Color.BLACK);
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
JTextField textField = new JTextField(FIELD_COLS);
textField.setFont(FONT);
textField.setHorizontalAlignment(JTextField.CENTER);
textComponentList.add(textField);
gridPanel.add(textField);
}
}
JPanel buttonPanel = new JPanel();
buttonPanel.add(new JButton(new ClearAllAction("Clear All", KeyEvent.VK_C)));
setLayout(new BorderLayout());
add(gridPanel);
add(buttonPanel, BorderLayout.PAGE_END);
}
private class ClearAllAction extends AbstractAction {
public ClearAllAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
textComponentList.stream().forEach(tc -> tc.setText(""));
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("ClearGrid");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new ClearGrid());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
createAndShowGui();
});
}
}
Related
i have a problem with adding a specific number of buttons from my for-loop to my JPanel, i know how to add all oof them, but i want to add only 1-10 (i havent decided yet, lets go with 10).'
this is my class where i just declare what objects i want to have.
private static int cID;
private static Deck[] card;
static ArrayList<JButton> buttonList = new ArrayList<JButton>();
private JFrame f;
private JPanel p1;
private JButton button;
public boolean isEmpty() {
return cID == 0;
}
public static void main(String[] args) {
CustomDecks c = new CustomDecks();
c.deckCreator();
}```
this is my for-loop where i create 420 buttons and give them names "card" + i where i is 0 - 419, yet when i try to add card0 to my panel, it fails, why?
private void deckCreator() {
card = new Deck[25];
new ArrayList<Cards> (cSet.cards);
for(int i = 0; i < 420; i++) {
button = new JButton();
buttonList.add(button);
button.setName("card" + i);
f.add(button);
p1.add(card0);
}
f.add(p1);
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.setVisible(true);
f.setExtendedState(Frame.MAXIMIZED_BOTH);
f.setUndecorated(true);
}
}
}
I'm not sure you can create a JPanel large enough to hold 420 JButtons.
Here's an example of a JButton GUI.
[
Generally, you create an application model and view separately. The model is made up of one or more plain Java classes. The view reads from the application model but doesn't update the model.
Your controller classes (ActionListener classes) update the application model and update / repaint the view.
This pattern is called the model / view / controller (MVC) pattern.
You can see in the example code below that the model is created in the view class constructor. Generally, you create the application model first, then you create the application view.
And here's the complete runnable code.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
public class JButtonScrollGUI {
private JFrame frame;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
new JButtonScrollGUI();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private String[] greekAlphabet;
public JButtonScrollGUI() {
this.greekAlphabet = new String[] { "alpha", "beta", "gamma", "epsilon", "zeta" };
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setTitle("Application");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createScrollPanel(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createScrollPanel() {
JPanel panel = new JPanel(new BorderLayout());
JPanel innerPanel = createButtonPanel();
Dimension d = innerPanel.getPreferredSize();
d.width += 50;
d.height /= 2;
panel.setPreferredSize(d);
JScrollPane scrollPane = new JScrollPane(innerPanel);
panel.add(scrollPane, BorderLayout.CENTER);
return panel;
}
private JPanel createButtonPanel() {
JPanel panel = new JPanel(new GridLayout(0, 3, 10, 10));
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
for (int i = 0; i < 20; i++) {
JButton button1 = new JButton("Previous " + i);
panel.add(button1);
JComboBox<String> selectorBox = new JComboBox<>(greekAlphabet);
panel.add(selectorBox);
JButton button2 = new JButton("Next " + i);
button2.setPreferredSize(button1.getPreferredSize());
panel.add(button2);
}
return panel;
}
}
I need to divide java swing window into many fields, something similar to the table or chess board. Color of each cell should be dependent on the object which this cell represents (each object has coordinates, which are changing during the game, so the color of each cell is not constant).
Additionally, if the user clicks on the empty field (white color), then a new random object is created and this object is assigned to these field (and field color is changing).
Which of java swing controls will be the best for these functionalities?
If I were you I would make 2 panel classes(white and black), the white one with a MouseAdapter, so that when one of the panels is clicked you can pull a random JLabel from an array. Here's an example that might help (roughly 120 lines):
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
public class ScratchPaper extends JFrame {
private static final long serialVersionUID = 1L;
private static final int GRIDSIZE = 8;
private JPanel[][] whitePanel = new WhitePanel[GRIDSIZE][GRIDSIZE];
private JPanel[][] blackPanel = new BlackPanel[GRIDSIZE][GRIDSIZE];
private Random rand = new Random();
JButton b1 = new JButton("Btn1");
JButton b2 = new JButton("Btn2");
JButton b3 = new JButton("Btn3");
JLabel l1 = new JLabel("Lbl1");
JLabel l2 = new JLabel("Lbl2");
JLabel l3 = new JLabel("Lbl3");
JPanel panel = new JPanel();
private JComponent[][] randObjects = {{b1, b2, b3}, {l1, l2, l3}, {panel, panel, panel}};
private Color[] randColors = {Color.RED, Color.ORANGE, Color.YELLOW, Color.GREEN, Color.BLUE, Color.MAGENTA};
public ScratchPaper() {
initGUI();
setTitle("EXAMPLE");
pack();
setLocationRelativeTo(null);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
private void initGUI() {
JPanel centerPanel = new JPanel();
centerPanel.setLayout(new GridLayout(GRIDSIZE, GRIDSIZE)); // makes 8*8 grid
add(centerPanel, BorderLayout.CENTER);
MouseAdapter ma = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
Component clickedComp = findComponentAt(e.getPoint());
JPanel target = (JPanel) clickedComp;
panel.setBackground(randColors[rand.nextInt(randColors.length)]);
if (target instanceof WhitePanel){
target.add(randObjects[rand.nextInt(randObjects.length)][rand.nextInt(randObjects[0].length)]);
target.updateUI();
}
}
};
addMouseListener(ma);
for (int row=0; row<GRIDSIZE; row++) {
for (int col=0; col<GRIDSIZE; col++) {
whitePanel[row][col] = new WhitePanel(row, col);
blackPanel[row][col] = new BlackPanel(row, col);
if ((row%2 == 0 && col%2 == 0) || ((row+1)%2 == 0 && (col+1)%2 == 0)) {
centerPanel.add(whitePanel[row][col]);
}
else {
centerPanel.add(blackPanel[row][col]);
}
}
}
}
public static void main(String args[]) {
try {
String className = UIManager.getCrossPlatformLookAndFeelClassName();
UIManager.setLookAndFeel(className);
} catch (Exception ex) {
System.out.println(ex);
}
EventQueue.invokeLater(new Runnable(){
#Override
public void run(){
new ScratchPaper();
}
});
}
class WhitePanel extends JPanel {
private static final int SIZE = 50;
public WhitePanel(int row, int col) {
Dimension size = new Dimension(SIZE, SIZE);
setPreferredSize(size);
setBackground(Color.WHITE);
}
}
class BlackPanel extends JPanel {
private static final int SIZE = 50;
public BlackPanel(int row, int col) {
Dimension size = new Dimension(SIZE, SIZE);
setPreferredSize(size);
setBackground(Color.BLACK);
}
}
}
Try running it! It's actually pretty fun!
This has been asked many times already, but i really cant solve this problem.
I'm trying to refresh a table in a JFRame while it is running after i added a row so I dont have to restart it.I've tried the following method, but it still doesnt work.
The method is used in a ActionListener.
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.JButton;
#SuppressWarnings("serial")
public class GUI2 extends JFrame {
private static JPanel contentPane;
private static JTable table;
/**
* Launch the application.
*/
public static void main(String[] args) {
GUI2 frame = new GUI2();
}
/**
* Create the frame.
*/
public GUI2() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane = new JPanel();
setContentPane(contentPane);
table = new JTable();
contentPane.add(table, BorderLayout.CENTER);
JButton btnRefresh = new JButton("Refresh");
contentPane.add(btnRefresh, BorderLayout.NORTH);
btnRefresh.addActionListener(new Refresh());
}
public class Refresh implements ActionListener{
public void actionPerformed(ActionEvent e){
repaintGUI();
}
}
public static void repaintGUI() {
contentPane.repaint();
contentPane.validate();
table.repaint();
table.validate();
}
}
Something similar to that. The Button is pressed after i have changed something in the table.
Your posted code doesn't work well as an example since the JTable is not visualized, but if you give the contentPane a BorderLayout, the JTable displays, and if refresh is pushed, then the GUI does in fact repaint, but as expected, it doesn't change its appearance since a simple repaint or revalidate won't change appearances if nothing else is done.
OK, here's where I need to guess since your question is still lacking key details (in the future, please ask it with an eye towards our point of view: people who have no idea what your current program does, looks like or what your problem is), but if the problem is that you're trying to reset a JTable's data, then the solution is to do just that -- reset your JTable's model by calling setRowCount(0) which will remove all data from the JTable, if it uses a DefaultTableModel. If it doesn't use the DefaultTableModel, then make sure to either give the JTable a new table model, or else call a method of your own table model that removes all data.
For instance:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.Random;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
public class GUI3 extends JPanel {
private static final String[] COLS = { "Foo", "Bar", "Baz" };
private static final int ROWS = 5;
private DefaultTableModel tableModel = new DefaultTableModel(COLS, ROWS);
private JTable table = new JTable(tableModel);
private ResetAction resetAction = new ResetAction("Reset", KeyEvent.VK_R);
private RandomizeAction randomizeAxn = new RandomizeAction("Randomize",
KeyEvent.VK_Z);
public GUI3() {
JPanel btnPanel = new JPanel();
btnPanel.add(new JButton(resetAction));
btnPanel.add(new JButton(randomizeAxn));
setLayout(new BorderLayout());
add(new JScrollPane(table));
add(btnPanel, BorderLayout.PAGE_END);
}
private class ResetAction extends AbstractAction {
public ResetAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
tableModel.setRowCount(0);
}
}
private class RandomizeAction extends AbstractAction {
private Random random = new Random();
public RandomizeAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
public void actionPerformed(ActionEvent e) {
tableModel.setRowCount(ROWS);
int rows = ROWS;
int columns = tableModel.getColumnCount();
for (int row = 0; row < rows; row++) {
for (int col = 0; col < columns; col++) {
int data = random.nextInt(10);
tableModel.setValueAt(data, row, col);
}
}
};
}
private static void createAndShowGui() {
GUI3 mainPanel = new GUI3();
JFrame frame = new JFrame("GUI3");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
I have created a setup of buttons using Box.
The problem is there are gaps between all the buttons.
Below is an MCVE version of my code. What I want to achieve is that the buttons "ONE" and "TWO" are touching side by side, with no gap, and buttons "ONE and "ONE" are touching top to bottom with no gap, and for this to continue throughout the setup.
I have read about glue and have tried to use it, but I have not been able to work it out. I am not able to use another layout other than Box as it will not fit in with the rest of my project.
public class Customers {
public static JFrame frame = new JFrame();
public static void frameGui(JPanel panel, String name){
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(panel);
frame.setSize(1200,500);
frame.setVisible(true);
}
public static void ScrollCustomersGui(){
Box box = Box.createVerticalBox();
box.add(customersTableHeadings(box));
box.add(customersTableHeadings(box));
box.add(customersTableHeadings(box));
box.add(customersTableHeadings(box));
JScrollPane scroll = new JScrollPane(box);
JPanel All = new JPanel(new BorderLayout());
All.add(scroll);
frameGui(All, "Customers");
}
public static JPanel customersTableHeadings(Box panel){
Font font = new Font("Courier", Font.BOLD,12);
JPanel customersTable = new JPanel();
JButton custid = new JButton("ONE");
JButton surname = new JButton("TWO");
customersTable.add(custid);
customersTable.add(surname);
return customersTable;
}
}
BoxLayout is designed to distribute unused space among components; struts, glue and filler won't change this. You can use the approach suggested here and here to alter the preferred size of the enclosing scroll pane. More generally, you can implement the scrollable interface. In addition, Swing GUI objects should be constructed and manipulated only on the event dispatch thread.
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
/** #se https://stackoverflow.com/a/26829171/230513 */
public class Customers {
private static final int N = 16;
private void display() {
Box box = Box.createVerticalBox();
for (int i = 0; i < N; i++) {
box.add(customersTableHeadings());
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(box) {
int w = box.getPreferredSize().width;
int h = box.getPreferredSize().height;
#Override
public Dimension getPreferredSize() {
return new Dimension(9 * w / 8, h / 3);
}
});
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private JPanel customersTableHeadings() {
JPanel customersTable = new JPanel();
JButton custid = new JButton("ONE");
JButton surname = new JButton("TWO");
customersTable.add(custid);
customersTable.add(surname);
return customersTable;
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
new Customers().display();
});
}
}
I found the answer myself. By adding the horizontal and vertical inside the same loop, and by enclosing this in a JApplet it closes the gap.
Below is a full working version of the code:
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import javax.swing.Box;
import javax.swing.JApplet;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
public class Box1 extends JApplet {
public void init() {
Box bv = Box.createVerticalBox();
box(bv);
JScrollPane scroll = new JScrollPane(bv);
JPanel All = new JPanel(new BorderLayout());
All.add(scroll);
Container cp = getContentPane();
cp.add(All);
}
public static void main(String[] args) {
frameGui(new Box1(), "Customers");
}
public static void frameGui (JApplet applet, String name) {
JFrame frame = new JFrame();
frame.getContentPane().removeAll();
frame.setTitle(name);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(applet);
frame.setSize(1200, 500);
applet.init();
applet.start();
frame.setVisible(true);
}
public static Box box(Box boxvert){
for (int i = 0; i < 50; i++){
JTextField one = new JTextField("ONE");
one.setMaximumSize(new Dimension (150,20));
JTextField two = new JTextField("TWO");
two.setMaximumSize(new Dimension (150,20));
Box horizontalBox = Box.createHorizontalBox();
horizontalBox.add(one);
horizontalBox.add(two);
boxvert.add(horizontalBox);
}
return boxvert;
}
}
I'm working on a school project where we have to create a virtual smartphone, to run on a computer.
My problem is that I need to create a keyboard on the screen (like on an smartphone), which you can then use by clicking with your mouse. I could just create every single JButton, but that will take a really long time. So I was hopping that someone knew some sort of algorithm that creates all the buttons and places them correctly on the screen.
Thank you in advance :)
You could construct the buttons through the use of for loops. One loop for every keyboard row is a plausible approach.
String row1 = "1234567890";
String row2 = "qwertyuiop";
// and so forth
String[] rows = { row1, row2, .. };
for (int i = 0; i < rows.length; i++) {
char[] keys = rows[i].toCharArray();
for (int j = 0; i < keys.length; j++) {
JButton button = new JButton(Character.toString(keys[j]));
// add button
}
}
// add special buttons like space bar
This could be done more elegantly through a more OOP approach, but this basic loop system will work.
This simple example might help you:
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
#SuppressWarnings("serial")
public class MainFrame extends JFrame
{
private JTextField txt;
private PopUpKeyboard keyboard;
public MainFrame()
{
super("pop-up keyboard");
setDefaultCloseOperation(EXIT_ON_CLOSE);
txt = new JTextField(20);
keyboard = new PopUpKeyboard(txt);
txt.addMouseListener(new MouseAdapter()
{
#Override
public void mouseClicked(MouseEvent e)
{
Point p = txt.getLocationOnScreen();
p.y += 30;
keyboard.setLocation(p);
keyboard.setVisible(true);
}
});
setLayout(new FlowLayout());
add(txt);
pack();
setLocationByPlatform(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
new MainFrame().setVisible(true);
}
});
}
private class PopUpKeyboard extends JDialog implements ActionListener
{
private JTextField txt;
public PopUpKeyboard(JTextField txt)
{
this.txt = txt;
setLayout(new GridLayout(3, 3));
for(int i = 1; i <= 9; i++) createButton(Integer.toString(i));
pack();
}
private void createButton(String label)
{
JButton btn = new JButton(label);
btn.addActionListener(this);
btn.setFocusPainted(false);
btn.setPreferredSize(new Dimension(100, 100));
Font font = btn.getFont();
float size = font.getSize() + 15.0f;
btn.setFont(font.deriveFont(size));
add(btn);
}
#Override
public void actionPerformed(ActionEvent e)
{
String actionCommand = e.getActionCommand();
txt.setText(txt.getText() + actionCommand);
}
}
}
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String alphabet = "abcdefghijklmnopqrstuvwxyz";
JFrame myFrame = new JFrame();
JPanel myPanel = new JPanel();
for (int i = 0; i < alphabet.length(); i++) {
myPanel.add(new JButton(alphabet.substring(i, i + 1)));
}
myFrame.add(myPanel);
myFrame.pack();
myFrame.setVisible(true);
}
This is a fast example of how to do it :).