How do I resize JComponents in GridLayout? - java

I'm new to Java programming. Can you help me with the layout of my first application (which is a simple calculator) please?
Here's the code I wrote:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class InputPad extends JFrame {
private JLabel statusLabel;
private JTextArea expTextArea;
InputPad() {
prepareGUI();
}
private void prepareGUI(){
JFrame mainFrame = new JFrame("My Calculator");
mainFrame.setSize(450,450);
mainFrame.setLayout(new GridLayout(3,2));
mainFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent){
System.exit(0);
}
});
JLabel headerLabel = new JLabel("Put your expression here:", JLabel.CENTER);
statusLabel = new JLabel("",JLabel.CENTER);
expTextArea = new JTextArea("1+(2^3*4)");
//Digits Panel
JPanel digitPanel = new JPanel();
GroupLayout layoutDigits = new GroupLayout(digitPanel);
digitPanel.setLayout(layoutDigits);
layoutDigits.setAutoCreateGaps(true);
layoutDigits.setAutoCreateContainerGaps(true);
//Operators Panel
JPanel operatorPanel = new JPanel();
GroupLayout layoutOperators = new GroupLayout(operatorPanel);
operatorPanel.setLayout(layoutOperators);
layoutOperators.setAutoCreateGaps(true);
layoutOperators.setAutoCreateContainerGaps(true);
JButton[] numButtons= new JButton[10];
int i;
for (i=0;i<10;i++){
numButtons[i] = new JButton(Integer.toString(i));
numButtons[i].addActionListener(e -> {
// TODO
});
}
JButton bEquals = new JButton("=");
bEquals.addActionListener(e -> {
// TODO
});
JButton bPlus = new JButton("+");
bPlus.addActionListener(e -> {
// TODO
});
JButton bMinus = new JButton("-");
bMinus.addActionListener(e -> {
// TODO
});
JButton bMultiply = new JButton("*");
bMultiply.addActionListener(e -> {
// TODO
});
JButton bDivide = new JButton("/");
bDivide.addActionListener(e -> {
// TODO
});
JButton bLeftParenthesis = new JButton("(");
bLeftParenthesis.addActionListener(e -> {
// TODO
});
JButton bRightParenthesis = new JButton(")");
bRightParenthesis.addActionListener(e -> {
// TODO
});
JButton bPower = new JButton("^");
bPower.addActionListener(e -> {
// TODO
});
JButton bDel = new JButton("←");
bDel.addActionListener(e -> {
// TODO
});
layoutDigits.setHorizontalGroup(
layoutDigits.createSequentialGroup()
.addGroup(layoutDigits.createParallelGroup(GroupLayout.Alignment.LEADING)
.addComponent(numButtons[7])
.addComponent(numButtons[4])
.addComponent(numButtons[1])
.addComponent(numButtons[0]))
.addGroup(layoutDigits.createParallelGroup(GroupLayout.Alignment.LEADING)
.addComponent(numButtons[8])
.addComponent(numButtons[5])
.addComponent(numButtons[2])
.addComponent(bEquals))
.addGroup(layoutDigits.createParallelGroup(GroupLayout.Alignment.LEADING)
.addComponent(numButtons[9])
.addComponent(numButtons[6])
.addComponent(numButtons[3]))
);
layoutDigits.setVerticalGroup(
layoutDigits.createSequentialGroup()
.addGroup(layoutDigits.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(numButtons[7])
.addComponent(numButtons[8])
.addComponent(numButtons[9]))
.addGroup(layoutDigits.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(numButtons[4])
.addComponent(numButtons[5])
.addComponent(numButtons[6]))
.addGroup(layoutDigits.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(numButtons[1])
.addComponent(numButtons[2])
.addComponent(numButtons[3]))
.addGroup(layoutDigits.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(numButtons[0])
.addComponent(bEquals))
);
layoutOperators.setHorizontalGroup(
layoutOperators.createSequentialGroup()
.addGroup(layoutOperators.createParallelGroup(GroupLayout.Alignment.LEADING)
.addComponent(bPlus)
.addComponent(bMinus)
.addComponent(bLeftParenthesis)
.addComponent(bPower))
.addGroup(layoutOperators.createParallelGroup(GroupLayout.Alignment.LEADING)
.addComponent(bMultiply)
.addComponent(bDivide)
.addComponent(bRightParenthesis)
.addComponent(bDel))
);
layoutOperators.setVerticalGroup(
layoutOperators.createSequentialGroup()
.addGroup(layoutOperators.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(bPlus)
.addComponent(bMultiply))
.addGroup(layoutOperators.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(bMinus)
.addComponent(bDivide))
.addGroup(layoutOperators.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(bLeftParenthesis)
.addComponent(bRightParenthesis))
.addGroup(layoutOperators.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(bPower)
.addComponent(bDel))
);
mainFrame.add(headerLabel);
mainFrame.add(expTextArea);
mainFrame.add(digitPanel);
mainFrame.add(operatorPanel);
mainFrame.add(statusLabel);
mainFrame.setVisible(true);
}
}
I tried the GridLayout for my JFrame, but I couldn't resize and of my JComponent except the main JFrame. Even I can't place two JPanels (side by side) in one cell of the GridLayout or expand a JLabel to two cells of the GridLayout.
This is what I got:
And here's what I want:

Let's start from the use of Layout Managers, from the link on the part of GridLayout
GridLayout simply makes a bunch of components equal in size and displays them in the requested number of rows and columns
So, this isn't what you want, but if you read the GridBagLayout part it says:
GridBagLayout is a sophisticated, flexible layout manager. It aligns components by placing them within a grid of cells, allowing components to span more than one cell. The rows in the grid can have different heights, and grid columns can have different widths.
We can combine both of them, along with a BoxLayout and you will get a similar output to what you're trying to achieve:
PLEASE NOTE:
Before posting the code, take note of the following tips:
You're extending JFrame and at the same time you're creating a JFrame object, this is discouraged, remove one of them, in this case as you're using the object and this is the recommended thing to do, simply remove the extends JFrame from your class. If you really need to extend something, don't extend JFrame but a JPanel instead.
Place your program inside the EDT, as I did in the main() method
Don't use System.exit(0); instead call setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) as shown in the above code
And now the code
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class CalculatorExample {
private JFrame frame;
private JTextArea area;
private JButton[][] digitsButtons, symbolsButtons;
private String[][] digitsText = {{"7", "8", "9"}, {"4", "5", "6"}, {"1", "2", "3"}, {"0", "="}}; //Looks strange but this will make the button adding easier
private String[][] symbolsText = {{"+", "*"}, {"-", "/"}, {"(", ")"}, {"^", "←"}};
private JPanel buttonsPane, areaAndResultsPane, digitsPane, symbolsPane;
private JLabel label;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new CalculatorExample().createAndShowGui();
}
});
}
public void createAndShowGui() {
frame = new JFrame("Calculator Example");
area = new JTextArea();
area.setRows(5);
area.setColumns(20);
label = new JLabel("Results go here");
digitsButtons = new JButton [4][3];
symbolsButtons= new JButton [4][2];
areaAndResultsPane = new JPanel();
areaAndResultsPane.setLayout(new BoxLayout(areaAndResultsPane, BoxLayout.PAGE_AXIS));
buttonsPane = new JPanel();
buttonsPane.setLayout(new GridLayout(1, 2, 10, 10));
digitsPane = new JPanel();
digitsPane.setLayout(new GridBagLayout());
symbolsPane = new JPanel();
symbolsPane.setLayout(new GridLayout(4, 2));
GridBagConstraints c = new GridBagConstraints();
for (int i = 0; i < digitsText.length; i++) {
for (int j = 0; j < digitsText[i].length; j++) {
digitsButtons[i][j] = new JButton(digitsText[i][j]);
}
}
for (int i = 0; i < symbolsText.length; i++) {
for (int j = 0; j < symbolsText[i].length; j++) {
symbolsButtons[i][j] = new JButton(symbolsText[i][j]);
}
}
areaAndResultsPane.add(area);
areaAndResultsPane.add(label);
boolean shouldBreak = false;
for (int i = 0; i < digitsButtons.length; i++) {
for (int j = 0; j < digitsButtons[i].length; j++) {
c.gridx = j;
c.gridy = i;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0.5;
if (i == 3) {
if (j == 1) {
c.gridwidth = 2; //This makes the "=" button larger
shouldBreak = true;
}
}
digitsPane.add(digitsButtons[i][j], c);
if (shouldBreak) {
break;
}
}
}
for (int i = 0; i < symbolsButtons.length; i++) {
for (int j = 0; j < symbolsButtons[i].length; j++) {
symbolsPane.add(symbolsButtons[i][j]);
}
}
frame.add(areaAndResultsPane, BorderLayout.NORTH);
buttonsPane.add(digitsPane);
buttonsPane.add(symbolsPane);
frame.add(buttonsPane, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
This was done nesting JPanels, each with a different layout, I hope it helps you to continue from here.

According to the Oracle documentation :
Each component takes all the available space within its cell, and each cell is exactly the same size.
So sadly, you can't resize any components inside a GridLayout.
You could instead use a GridBagLayout. It is a little bit more complicated to understand but offers more features. I let you make some tests with the documentation to get in touch with it !

Related

How to Create JPanels in a Loop and insert them in JPanel Array [] []

Hi guys I'm using Eclipse and I'm trying to create a Connect4 Game Grid , which is an JPanel gridArray [6] [7]. I later add the different Panels for buttons and the grid into a main panel and add it into my frame.
My Problem:
I want to fill the gridArray JPanel with Pictures of an empty field(white color) but first of all i want to create a new Panel and insert it into my gridArray through a loop until gridArray has all 42 Panels inside it and is fully filled. I have my Code below but somehow it doesnt work, although my logic should be fine.
I tried it with using a helper Function to create a new JPanel and call the function for each loop in fillGrid();, basically calling it 42 times but it still wont work...
I will gladly appreciate some help!
package connect4;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class GridTest extends JFrame {
JFrame mainWindow;
JPanel buttonPanel, mainPanel;
JPanel gridPanel;
JPanel emptyPanel;
JPanel panel1;
ImageIcon emptyBox;
JPanel[][] gridArray;
JLabel emptyLabel;
JButton arrow1,arrow2,arrow3,arrow4,arrow5,arrow6,arrow7;
public GridTest() {
createGameGrid();
fillGrid();
}
public void createGameGrid() {
//creating window and mainpanel
mainWindow = new JFrame("Connect 4");
mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
//defining top panel with 7 buttons;
buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(1, 7));
arrow1 = new JButton("V");
arrow2 = new JButton("V");
arrow3 = new JButton("V");
arrow4 = new JButton("V");
arrow5 = new JButton("V");
arrow6 = new JButton("V");
arrow7 = new JButton("V");
buttonPanel.add(arrow1);
buttonPanel.add(arrow2);
buttonPanel.add(arrow3);
buttonPanel.add(arrow4);
buttonPanel.add(arrow5);
buttonPanel.add(arrow6);
buttonPanel.add(arrow7);
//create Grind Panel
gridPanel = new JPanel();
gridPanel.setLayout(new GridLayout(6,7));
mainPanel.add(buttonPanel, BorderLayout.NORTH);
mainPanel.add(gridPanel, BorderLayout.SOUTH);
mainWindow.add(mainPanel);
mainWindow.pack();
mainWindow.setLocationRelativeTo(null);
mainWindow.setVisible(true);
}
private JPanel greateOnePanel(){
//here we need to insert the icon which is in empty box into a newly created panel
//ifirst wanted to insert black panels do ensure it works as intended but it doesnt
JPanel panel = new JPanel();
panel.setBackground(Color.BLACK);
panel.setSize(50,50);
return panel;
}
//here we need to fill the grid with the panels created above from left to right...
public void fillGrid() {
for(int j = 0; j < 6; j++) {
for (int k = 0; k < 7; k++) {
gridPanel.add(greateOnePanel());
}
}
}
public static void main(String[] args) {
new GridTest();
}
}
i tried it with this method using gridArray, but it throws NullPointer Exeptions and wont fill the grid with simple textlabels "Hallo" (just for testing purposes)
public void fillGrid() {
for(int j = 0; j < 6; j++) {
for (int k = 0; k < 7; k++) {
JLabel label = new JLabel("Hallo");
gridArray[j][k] = new JPanel();
gridArray[j][k].setSize(50, 50);
gridArray[j][k].setBackground(Color.RED);
gridArray[j][k].add(label);
gridPanel.add(gridArray[j][k]);
}
}
}
Here is a short, self contained, code that should help with various aspects of the task.
There is no need for a panel in each cell. The only thing it helped with was setting a BG color. That can be done in a label as long as the background is set to opaque.
This code defines a SquareLabel which overrides getPreferredSize() to return the maximum of preferred width and height as the value of both (usually it is the width).
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class SquareLabelGrid {
int rows = 6;
int cols = 7;
JLabel[][] labelArray = new JLabel[cols][rows];
Font bigFont = new Font(Font.SANS_SERIF, Font.BOLD, 30);
Insets labelInsets;
SquareLabelGrid() {
JPanel gameBoard = new JPanel(new GridLayout(rows, cols));
// a border to make the cell boundaries more clear and add
// some space around the text
Border border = new CompoundBorder(
new LineBorder(Color.BLACK),new EmptyBorder(4,4,4,4));
for (int yy = 0; yy < rows; yy++) {
for (int xx = 0; xx < cols; xx++) {
JLabel l = getColoredSquareLabel(xx, yy);
labelArray[xx][yy] = l;
gameBoard.add(l);
l.setBorder(border);
}
}
JOptionPane.showMessageDialog(null, gameBoard);
}
private JLabel getColoredSquareLabel(int x, int y) {
SquareLabel label = new SquareLabel(
String.format("%1s,%1s", (x+1), (y+1)));
label.setFont(bigFont);
label.setOpaque(true); // so we can see the BG color
label.setBackground(Color.ORANGE); // I prefer orange!
// make the GUI less 'crowded'
label.setBorder(new EmptyBorder(4,4,4,4));
return label;
}
public static void main(String[] args) {
Runnable r = () -> {
new SquareLabelGrid();
};
SwingUtilities.invokeLater(r);
}
}
class SquareLabel extends JLabel {
SquareLabel(String label) {
super(label);
}
/* This will create a square component that accounts for the
size of the String / Icon it contains. No guesswork! */
#Override
public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
int w = d.width;
int h = d.height;
int sz = w > h ? w : h;
return new Dimension(sz, sz);
}
}
The problem is that you have not initialized the grid array .
Otherwise it will throw Null pointer exception.
JPanel[][] gridArray = new JPanel[6][8];
Also set the preferred size of main panel to make the grids visible .
mainPanel.setPreferredSize(new Dimension(400, 200));
Here is what i can see when I run your code with the modifications mentioned here .
Also please execute it from main with following code .
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
new GridTest();
}
});
}

Displaying JLabel matrix

Can somebody tell me why after calling method getContentPane().add(grid[i][j]) I am not able to display the matrix of JLabels. There's only one "e" label displayed.
public class SudokuFrame extends JFrame implements ActionListener {
JButton generateButton;
JLabel[][] grid;
public SudokuFrame(){
setSize(300, 300);
setTitle("Sudoku");
setLayout(null);
generateButton = new JButton("Generate");
generateButton.setBounds(90, 220, 100, 30);
add(generateButton);
generateButton.addActionListener(this);
grid = new JLabel[9][9];
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
grid[i][j] = new JLabel("e");
grid[i][j].setBounds(100, 100, 30, 30);
getContentPane().add(grid[i][j]);
}
}
}
public static void main(String[] args){
SudokuFrame frame = new SudokuFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
You're giving every JLabel the exact same bounds -- same size and same position and so every new label is placed right smack dab on top of the previously added ones.
Solution: don't use null layout. Why use this when the problem is perfectly suited for a GridLayout? In general you want to avoid using null layouts and setBounds as the layout managers will make your coding and your GUI much easier to manage. Let the layouts do the heavy lifting for you.
e.g.,
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import javax.swing.*;
public class SimpleSudoku extends JPanel {
private static final int GAP = 1;
private static final Font LABEL_FONT = new Font(Font.DIALOG, Font.PLAIN, 24);
private JLabel[][] grid = new JLabel[9][9];
public SimpleSudoku() {
JPanel sudokuPanel = new JPanel(new GridLayout(9, 9, GAP, GAP));
sudokuPanel.setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
sudokuPanel.setBackground(Color.BLACK);
for (int row = 0; row < grid.length; row++) {
for (int col = 0; col < grid[row].length; col++) {
grid[row][col] = new JLabel(" ", SwingConstants.CENTER);
grid[row][col].setFont(LABEL_FONT); // make it big
grid[row][col].setOpaque(true);
grid[row][col].setBackground(Color.WHITE);
sudokuPanel.add(grid[row][col]);
}
}
JPanel bottomPanel = new JPanel();
bottomPanel.add(new JButton("Regenerate"));
setLayout(new BorderLayout());
add(sudokuPanel, BorderLayout.CENTER);
add(bottomPanel, BorderLayout.PAGE_END);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
createAndShowGui();
});
}
private static void createAndShowGui() {
SimpleSudoku mainPanel = new SimpleSudoku();
JFrame frame = new JFrame("SimpleSudoku");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}

automated buttons implementation in java

I want to have a for loop, that can implement and add a specified number of JButtons the one after the other. I was trying to implement it and this is my code so far:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ArrayForm extends JFrame implements ActionListener
{
JPanel numPanel = new JPanel();
JPanel opPanel = new JPanel();
JTextField textField = new JTextField(25);
JButton [] buttons = new JButton[10];
JButton [] OPbuttons = new JButton[6];
String num="";
String [] operation = {"+","-","*","/","=","C"};
public static void main(String[] args)
{ArrayForm fobject = new ArrayForm();}
public ArrayForm()
{
setLayout(new FlowLayout());
setSize(400,300);
setTitle("Calculator");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
numPanel.setPreferredSize(new Dimension(180,150));
numPanel.setLayout(new FlowLayout());
opPanel.setPreferredSize(new Dimension(200,70));
opPanel.setLayout(new FlowLayout());
for (int i = 0; i<10; i++)
{
//The code in here
}
for (int i = 0; i<6; i++)
{
//The code in here
}
add(textField);
this.textField.setEditable(false);
add(numPanel);
add(opPanel);
setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e)
{
}
}
Can you please help me with for loop part? where the first one is buttons array, and the second one is for OPbuttons array.
Your for loop part might be as follows:
for (int i = 0; i<10; i++)
{
buttons[i] = new JButton(""+i);
numPanel.add(buttons[i]);
buttons[i].addActionListener(this);
}
for (int i = 0; i<6; i++)
{
OPbuttons[i] = new JButton(operation[i]);
opPanel.add(OPbuttons[i]);
OPbuttons[i].addActionListener(this);
}
What i have understood, is that you are trying to add the buttons of a calculator automatically, within two different panels...
NB: don't forget to add the code for your Action Listener.

Simple GUI guidance. Can I stick with BorderLayout or do I need something else?

I'm trying to create a GUI for a personal project. I have a file chooser, a console area, a text field (with label), a button panel(2 buttons) and finally a "drop zone" area.
The GUI is divided vertically in half with the console on the right.
On the UpperLeft I have FileChooser positioned at BorderLayout.CENTER, followed by the ButtonPanel at BorderLayout.SOUTH.
Below that is the "drop zone"
It currently looks something like this:
_________________
| file | console|
| chooser| |
| buttons| |
|--------| |
| drop | |
| zone | |
|________|________|
I want to add a new text field between the file chooser and the button panel, but when I change file chooser to NORTH, jtextfield to CENTER and buttons to SOUTH, the file chooser is weirdly small and the jtextfield is much to large. I think this is just due to the inherent properties of BorderLayout, but I am not sure. Should I use a different Layout and what kind of changes would I make?
I've included the code I'm working with below. Thank you for any help in advance!
import java.awt.datatransfer.*;
import java.awt.event.*;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.io.*;
import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.border.TitledBorder;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.filechooser.FileSystemView;
import javax.swing.text.*;
import java.util.*;
import java.nio.*;
public class ConsolidatorDemo extends JPanel implements ActionListener {
JFileChooser fc;
JButton clear;
JButton ok;
JTextArea console;
JList<File> dropZone;
DefaultListModel listModel;
JSplitPane childSplitPane, parentSplitPane;
PrintStream ps;
JTextField wordCount;
JLabel lblCount;
public ConsolidatorDemo() {
super(new BorderLayout());
fc = new JFileChooser();;
fc.setMultiSelectionEnabled(true);
fc.setDragEnabled(true);
fc.setControlButtonsAreShown(false);
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
JPanel fcPanel = new JPanel(new BorderLayout());
fcPanel.add(fc, BorderLayout.CENTER);
clear = new JButton("Clear All");
clear.addActionListener(this);
JPanel buttonPanel = new JPanel(new BorderLayout());
buttonPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
buttonPanel.add(clear, BorderLayout.LINE_END);
ok = new JButton("OK");
ok.addActionListener(this);
buttonPanel.add(ok, BorderLayout.WEST);
JPanel sizePanel = new JPanel(new BorderLayout());
sizePanel.setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
wordCount = new JTextField();
sizePanel.add(wordCount, BorderLayout.LINE_END);
// lblCount = new JLabel("Word Counter");
// buttonPanel.add(lblCount, BorderLayout.CENTER);
JPanel leftUpperPanel = new JPanel(new BorderLayout());
leftUpperPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
leftUpperPanel.add(fcPanel, BorderLayout.NORTH);
leftUpperPanel.add(sizePanel, BorderLayout.CENTER);
leftUpperPanel.add(buttonPanel, BorderLayout.PAGE_END);
JScrollPane leftLowerPanel = new javax.swing.JScrollPane();
leftLowerPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
listModel = new DefaultListModel();
dropZone = new JList(listModel);
dropZone.setCellRenderer(new FileCellRenderer());
dropZone.setTransferHandler(new ListTransferHandler(dropZone));
dropZone.setDragEnabled(true);
dropZone.setDropMode(javax.swing.DropMode.INSERT);
dropZone.setBorder(new TitledBorder("Selected files/folders"));
leftLowerPanel.setViewportView(new JScrollPane(dropZone));
childSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
leftUpperPanel, leftLowerPanel);
childSplitPane.setDividerLocation(400);
childSplitPane.setPreferredSize(new Dimension(480, 650));
console = new JTextArea();
console.setColumns(40);
console.setLineWrap(true);
console.setBorder(new TitledBorder("Console"));
parentSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
childSplitPane, console);
parentSplitPane.setDividerLocation(480);
parentSplitPane.setPreferredSize(new Dimension(800, 650));
add(parentSplitPane, BorderLayout.CENTER);
this.redirectSystemStreams();
}
private void updateTextArea(final String text) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
console.append(text);
}
});
}
private void redirectSystemStreams() {
OutputStream out = new OutputStream() {
#Override
public void write(int b) throws IOException {
updateTextArea(String.valueOf((char) b));
}
#Override
public void write(byte[] b, int off, int len) throws IOException {
updateTextArea(new String(b, off, len));
}
#Override
public void write(byte[] b) throws IOException {
write(b, 0, b.length);
}
};
System.setOut(new PrintStream(out, true));
System.setErr(new PrintStream(out, true));
}
public void setDefaultButton() {
getRootPane().setDefaultButton(ok);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == clear) {
listModel.clear();
}
if(e.getSource() == ok){
try{
if(dropZone.isSelectionEmpty() == true){
int start = 0;
int end = dropZone.getModel().getSize() - 1;
if (end >= 0) {
dropZone.setSelectionInterval(start, end);
}
}
List<File> list = dropZone.getSelectedValuesList();
for (File file : list) {
//StringEditing.editDocument(file, Integer.parseInt(wordCount.getText()));
}
}
catch(NumberFormatException nfe){
System.out.println("You did not input a number");
}
catch(Exception ef){
System.out.println("Something is wrong!");
}
}
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Make sure we have nice window decorations.
JFrame.setDefaultLookAndFeelDecorated(true);
try {
//UIManager.setLookAndFeel("de.javasoft.plaf.synthetica.SyntheticaBlackStarLookAndFeel");
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
}catch (Exception e){
e.printStackTrace();
}
//Create and set up the window.
JFrame frame = new JFrame("Consolidator!");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
//Create and set up the menu bar and content pane.
ConsolidatorDemo demo = new ConsolidatorDemo();
demo.setOpaque(true); //content panes must be opaque
frame.setContentPane(demo);
//Display the window.
frame.pack();
frame.setVisible(true);
demo.setDefaultButton();
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
class FileCellRenderer extends DefaultListCellRenderer {
public Component getListCellRendererComponent(JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
Component c = super.getListCellRendererComponent(
list,value,index,isSelected,cellHasFocus);
if (c instanceof JLabel && value instanceof File) {
JLabel l = (JLabel)c;
File f = (File)value;
l.setIcon(FileSystemView.getFileSystemView().getSystemIcon(f));
l.setText(f.getName());
l.setToolTipText(f.getAbsolutePath());
}
return c;
}
}
class ListTransferHandler extends TransferHandler {
private JList list;
ListTransferHandler(JList list) {
this.list = list;
}
#Override
public boolean canImport(TransferHandler.TransferSupport info) {
// we only import FileList
if (!info.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
return false;
}
return true;
}
#Override
public boolean importData(TransferHandler.TransferSupport info) {
if (!info.isDrop()) {
return false;
}
// Check for FileList flavor
if (!info.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
displayDropLocation("List doesn't accept a drop of this type.");
return false;
}
// Get the fileList that is being dropped.
Transferable t = info.getTransferable();
List<File> data;
try {
data = (List<File>)t.getTransferData(DataFlavor.javaFileListFlavor);
}
catch (Exception e) { return false; }
DefaultListModel model = (DefaultListModel) list.getModel();
for (Object file : data) {
model.addElement((File)file);
}
return true;
}
private void displayDropLocation(String string) {
System.out.println(string);
}
}
I ended up using GridBagLayout using the various answers here, thank you for your help!
I've got a ton of extra/ unused stuff in this example, mostly because I was starting to implement the functions I needed when I figured I'd post an update here. Should still compile and run fine though.
One problem I have is that the GUI spawns with the button panel / drop zone divider sort of eating into each other. On top of that, there is a text field which has no width despite it working perfectly fine before I used the split panes. If anyone had any knowledge of how to get around these bugs I'd appreciate it!
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.*;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import java.awt.datatransfer.*;
import java.awt.event.*;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.io.*;
import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.border.TitledBorder;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.filechooser.FileSystemView;
import javax.swing.text.*;
import java.util.*;
import java.nio.*;
public class TestGridBagLayout {
final static boolean shouldFill = true;
final static boolean shouldWeightX = true;
final static boolean RIGHT_TO_LEFT = false;
public static void addComponentsToPane(Container pane) {
if (RIGHT_TO_LEFT) {
pane.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
}
JButton clear;
JButton ok;
JLabel num;
JTextField input;
JSplitPane childSplitPane, parentSplitPane;
PrintStream ps;
JTextArea console;
JList<File> dropZone;
DefaultListModel listModel;
pane.setLayout(new GridBagLayout());
JPanel leftUpperPanel = new JPanel(new GridBagLayout());
leftUpperPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
GridBagConstraints c = new GridBagConstraints();
if (shouldFill) {
//natural height, maximum width
c.fill = GridBagConstraints.HORIZONTAL;
}
JFileChooser fc = new JFileChooser();;
fc.setMultiSelectionEnabled(true);
fc.setDragEnabled(true);
fc.setControlButtonsAreShown(false);
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
c.fill = GridBagConstraints.HORIZONTAL;
c.ipady = 40; //make this component tall
c.weightx = 0.0;
c.gridwidth = 4;
c.gridx = 0;
c.gridy = 1;
leftUpperPanel.add(fc, c);
ok = new JButton("OK");
c.fill = GridBagConstraints.HORIZONTAL;
c.ipady = 0; //reset to default
c.anchor = GridBagConstraints.PAGE_END; //bottom of space
c.insets = new Insets(10,0,0,0); //top padding
c.weightx = 0.5;
c.gridx = 0; //aligned with button 2
c.gridwidth = 1;
c.gridy = 2; //third row
leftUpperPanel.add(ok, c);
num = new JLabel("Word Count:");
c.fill = GridBagConstraints.NONE;
c.anchor = GridBagConstraints.PAGE_END;
c.insets = new Insets(10,0,0,0); //top padding
c.weightx = 0.25;
c.gridx = 1;
c.gridy = 2;
leftUpperPanel.add(num, c);
input = new JTextField("", 50);
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.PAGE_END;
c.insets = new Insets(10,0,0,0); //top padding
c.weightx = 0.25;
c.gridx = 2;
c.gridy = 2;
leftUpperPanel.add(input, c);
clear = new JButton("Clear All");
c.fill = GridBagConstraints.HORIZONTAL;
c.ipady = 0;
c.anchor = GridBagConstraints.PAGE_END;
c.insets = new Insets(10,0,0,0); //top padding
c.weightx = 0.5;
c.gridx = 3;
c.gridy = 2;
leftUpperPanel.add(clear, c);
JScrollPane leftLowerPanel = new javax.swing.JScrollPane();
leftLowerPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
listModel = new DefaultListModel();
dropZone = new JList(listModel);
dropZone.setCellRenderer(new FileCellRenderer());
dropZone.setTransferHandler(new ListTransferHandler(dropZone));
dropZone.setDragEnabled(true);
dropZone.setDropMode(javax.swing.DropMode.INSERT);
dropZone.setBorder(new TitledBorder("Selected files/folders"));
leftLowerPanel.setViewportView(new JScrollPane(dropZone));
childSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
leftUpperPanel, leftLowerPanel);
childSplitPane.setDividerLocation(400);
childSplitPane.setPreferredSize(new Dimension(480, 650));
console = new JTextArea();
console.setColumns(40);
console.setLineWrap(true);
console.setBorder(new TitledBorder("Console"));
parentSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
childSplitPane, console);
parentSplitPane.setDividerLocation(480);
parentSplitPane.setPreferredSize(new Dimension(800, 650));
pane.add(parentSplitPane);
}
public static void initUI() {
JFrame frame = new JFrame("GridBagLayoutDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addComponentsToPane(frame.getContentPane());
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
TestGridBagLayout testMultiplePanels = new TestGridBagLayout();
testMultiplePanels.initUI();
}
});
}
}
You could start by using a GridLayout setup to display two columns and one row. This would start out as the primary display/container/panel for the vertical split. You would then need another JPanel, possibly with a GridLayout setup to display one column and two rows, this would display the file chooser and drop zone.
You would then add this panel and the text area to the primary panel.
You could also do this using a single GridBagLaout, but you might find using compound GridLayouts easier.
See How to Use GridLayout and How to Use GridBagLayout for more details
I would probably create a panel with BoxLayout with a y-axis orientation, and put my 'two halves' in that, and put it on the west end of the JFrame's default BoxLayout. Then I'd put the other panel in the center, assuming you want it to stretch and shrink in both directions as the user changes the window size.
For flexibility, you could use a JSplitPane having HORIZONTAL_SPLIT; put the console on the right and a nested JSplitPane having VERTICAL_SPLIT on the left to hold the fcPanel and dropZone.

Numeric Keypad more efficient way

Is there more efficient way to add button R, 0 and E? Is it possible to somehow add them to the array?
public Keypad() {
setTitle("Keypad");
setSize(220, 250);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setLayout(new GridLayout(4, 3, 2, 2));
JButton[] buttonArray = new JButton[10];
for (int i = 1; i < buttonArray.length; i++) {
buttonArray[i] = new JButton(String.valueOf(i));
add(buttonArray[i]);
buttonArray[i].addActionListener(this);
}
add(buttonR);
add(button0);
add(buttonE);
setVisible(true);
setResizable(false);
}
You can't get much more efficient than you are already now. You could maybe slightly reorganize the code to move the addition of the ActionListener and the addition of the button to the hierarchy in a single method. Also, the JButton[] is useless so drop it, you will save a few bytes in memory (but really nothing major):
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class Keypad extends JFrame implements ActionListener {
private JButton buttonR = new JButton("R");
private JButton button0 = new JButton("0");
private JButton buttonE = new JButton("E");
public Keypad() {
setTitle("Keypad");
setSize(220, 250);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setLayout(new GridLayout(4, 3, 2, 2));
for (int i = 1; i < 10; i++) {
addButton(new JButton(String.valueOf(i)));
}
addButton(buttonR);
addButton(button0);
addButton(buttonE);
setResizable(false);
setVisible(true);
}
private void addButton(JButton button) {
button.addActionListener(this);
add(button);
}
#Override
public void actionPerformed(ActionEvent e) {
}
}
"Is it possible to somehow add them to the array?"
Yes you can do this if that is what you want
JButton[] buttonArray = new JButton[10];
for (int i = 1; i < buttonArray.length+3; i++) {
if(i<buttonArray.length){
buttonArray[i] = new JButton(String.valueOf(i));
add(buttonArray[i]);
buttonArray[i].addActionListener(this);
}
if(i==buttonArray.length+1){add(buttonR);}
if(i==buttonArray.length+2){add(button0);}
if(i==buttonArray.length+3){add(buttonE);}
}
This does what you want but AFAIK there is no quicker way to do this.

Categories

Resources