I'm currently working on a program which is for school. We have to make an Applet and I have opted for JApplet. For some reason, the panel which I am using to display a specific string will not show. What might be the issue here? Please point me in the right direction. Also, I looked at a few a tutorials, some suggested that I have "start", "stop" and "destory" methods and some didn't. Do any of these methods have an effect on why my JPanel won't show the graphic?
Thank you
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class Shape extends JApplet {
/**
*
*/
private static final long serialVersionUID = 1L;
// making the radiobuttons for the shape choices
JRadioButton squareButton = new JRadioButton("Square",true);
JRadioButton ovalButton = new JRadioButton("Oval",false);
JRadioButton rectangleButton = new JRadioButton("Rectangle",false);
JRadioButton triangleButton = new JRadioButton("Triangle",false);
// making radiobuttons for the color choices
JRadioButton redButton = new JRadioButton("Red",true);
JRadioButton blueButton = new JRadioButton("Blue",false);
JRadioButton greenButton = new JRadioButton("Green",false);
JRadioButton yellowButton = new JRadioButton("Yellow",false);
// making buttons draw and animate
JButton drawButton = new JButton("Draw!");
JButton animateButton = new JButton("Animate!");
// making JTextFields for length and width
JTextField lengthField = new JTextField("Enter a length",15);
JTextField widthField = new JTextField("Enter a width",15);
// making JPanel, in which the radiobuttons will go01
JPanel shapePanel = new JPanel();
JPanel colorPanel = new JPanel();
JPanel buttonPanel = new JPanel();
JPanel textPanel = new JPanel();
drawPanel dPanel;
ButtonGroup shapeGroup = new ButtonGroup();
ButtonGroup colorGroup = new ButtonGroup();
// variables that will dictates the shape, size and color
int length = 200;
int width = 200;
Color color = Color.RED;
String shape = "square";
public void init() {
setLayout(new FlowLayout()); // setting layout for the applet
setSize(680,480);
// setting the layout for the shapePanel - gridlayout 2 rows, 2 cols and space of 5
shapePanel.setLayout(new GridLayout(2,2,5,5));
// adding a border to the shapePanel to indicate to the user what it does "titledBorder"
shapePanel.setBorder(BorderFactory.createTitledBorder("Choose a shape"));
// setting layout for the color panel - gridlayout 2 rows, 2 cols and space of 5
colorPanel.setLayout(new GridLayout(2,2,5,5));
// adding a border to the colorPanel to indicate to the user what it does "titledBorder"
colorPanel.setBorder(BorderFactory.createTitledBorder("Choose a color"));
// setting the layout for the buttonPanel - gridlayout 1 row, 2 cols and space of 5
buttonPanel.setLayout(new GridLayout(1,2,5,5));
// adding a color border
buttonPanel.setBorder(BorderFactory.createLineBorder(Color.red, 2));
// setting the layout of the textField - gridlayout 1 row, 2 cols and space of 5
textPanel.setLayout(new GridLayout(1,2,5,5));
// adding some attributes for lengthField and widthField
lengthField.setFont(new Font("Arial",Font.PLAIN,12));
lengthField.setForeground(new Color(150,150,150));
widthField.setFont(new Font("Arial",Font.PLAIN,12));
widthField.setForeground(new Color(150,150,150));
// using shapegroup to organize the JRadioButtons
shapeGroup.add(squareButton);
shapeGroup.add(ovalButton);
shapeGroup.add(rectangleButton);
shapeGroup.add(triangleButton);
// using colorgroup to organize the color radiobuttons
colorGroup.add(redButton);
colorGroup.add(blueButton);
colorGroup.add(greenButton);
colorGroup.add(yellowButton);
// add the shape buttons to the panel so they appear in a square form
shapePanel.add(squareButton);
shapePanel.add(ovalButton);
shapePanel.add(rectangleButton);
shapePanel.add(triangleButton);
// adding color buttons to the color panel
colorPanel.add(redButton);
colorPanel.add(blueButton);
colorPanel.add(greenButton);
colorPanel.add(yellowButton);
// adding jbuttons
buttonPanel.add(drawButton);
buttonPanel.add(animateButton);
// adding textfields to the textPanel
textPanel.add(lengthField);
textPanel.add(widthField);
dPanel = new drawPanel();
// adding panels to the applet
add(shapePanel);
add(colorPanel);
add(buttonPanel);
add(textPanel);
add(dPanel);
// adding focus listener to lengthField and widthField
lengthField.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent e) {
lengthField.setText("");
lengthField.setForeground(Color.black);
}
public void focusLost(FocusEvent e) {}
});
widthField.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent e) {
widthField.setText("");
widthField.setForeground(Color.black);
}
public void focusLost(FocusEvent e) {}
});
drawButton.addActionListener(new drawListener());
}
// when the person presses paint, this will be executed to paint the specific shape, color with the width and length
class drawListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
int mylength = 5;
int mywidth = 5;
try {
mylength = Integer.parseInt(lengthField.getText());;
mywidth = Integer.parseInt(widthField.getText());;
}catch(Exception ex) {
JOptionPane.showMessageDialog(null,""+ex,"",JOptionPane.ERROR_MESSAGE);
}
if((mylength > 200 || mylength < 5)) {
JOptionPane.showMessageDialog(null, "Please make sure the number is above 5 and less than 200",
"Invalid length message", JOptionPane.ERROR_MESSAGE);
}else if((mywidth > 200 || mywidth < 5)) {
JOptionPane.showMessageDialog(null, "Please make sure the number is above 5 and less than 200",
"Invalid width message", JOptionPane.ERROR_MESSAGE);
}else {
length = mylength;
width = mywidth;
// checking which color button is selected
if(redButton.isSelected()) {
color = Color.RED;
}else if(blueButton.isSelected()) {
color = Color.BLUE;
}else if(greenButton.isSelected()) {
color = Color.GREEN;
}else if(yellowButton.isSelected()) {
color = Color.YELLOW;
}
// checking which shape has been selected
if(rectangleButton.isSelected()) {
shape = "rectangle";
}else if(triangleButton.isSelected()) {
shape = "triangle";
}else if(ovalButton.isSelected()) {
shape = "oval";
}else if(squareButton.isSelected()) {
shape = "square";
}
//System.out.printf("%3d %3d %s %s \n",length,width,shape,color);
}
}
}
// This will be used to do the painting
class drawPanel extends JPanel {
private static final long serialVersionUID = 1L;
//Paint Method
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.black);
g2.drawString("My awesome string", 200, 200);
}
}
}
A JPanel with no components has a default size of 0x0. Try this source:
// <applet code=Shape width=640 height=480></applet>
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Shape extends JApplet {
/**
*
*/
private static final long serialVersionUID = 1L;
// making the radiobuttons for the shape choices
JRadioButton squareButton = new JRadioButton("Square",true);
JRadioButton ovalButton = new JRadioButton("Oval",false);
JRadioButton rectangleButton = new JRadioButton("Rectangle",false);
JRadioButton triangleButton = new JRadioButton("Triangle",false);
// making radiobuttons for the color choices
JRadioButton redButton = new JRadioButton("Red",true);
JRadioButton blueButton = new JRadioButton("Blue",false);
JRadioButton greenButton = new JRadioButton("Green",false);
JRadioButton yellowButton = new JRadioButton("Yellow",false);
// making buttons draw and animate
JButton drawButton = new JButton("Draw!");
JButton animateButton = new JButton("Animate!");
// making JTextFields for length and width
JTextField lengthField = new JTextField("Enter a length",15);
JTextField widthField = new JTextField("Enter a width",15);
// making JPanel, in which the radiobuttons will go01
JPanel shapePanel = new JPanel();
JPanel colorPanel = new JPanel();
JPanel buttonPanel = new JPanel();
JPanel textPanel = new JPanel();
drawPanel dPanel;
ButtonGroup shapeGroup = new ButtonGroup();
ButtonGroup colorGroup = new ButtonGroup();
// variables that will dictates the shape, size and color
int length = 200;
int width = 200;
Color color = Color.RED;
String shape = "square";
public void init() {
setLayout(new FlowLayout()); // setting layout for the applet
// This is set by HTML!
//setSize(680,480);
// setting the layout for the shapePanel - gridlayout 2 rows, 2 cols and space of 5
shapePanel.setLayout(new GridLayout(2,2,5,5));
// adding a border to the shapePanel to indicate to the user what it does "titledBorder"
shapePanel.setBorder(BorderFactory.createTitledBorder("Choose a shape"));
// setting layout for the color panel - gridlayout 2 rows, 2 cols and space of 5
colorPanel.setLayout(new GridLayout(2,2,5,5));
// adding a border to the colorPanel to indicate to the user what it does "titledBorder"
colorPanel.setBorder(BorderFactory.createTitledBorder("Choose a color"));
// setting the layout for the buttonPanel - gridlayout 1 row, 2 cols and space of 5
buttonPanel.setLayout(new GridLayout(1,2,5,5));
// adding a color border
buttonPanel.setBorder(BorderFactory.createLineBorder(Color.red, 2));
// setting the layout of the textField - gridlayout 1 row, 2 cols and space of 5
textPanel.setLayout(new GridLayout(1,2,5,5));
// adding some attributes for lengthField and widthField
lengthField.setFont(new Font("Arial",Font.PLAIN,12));
lengthField.setForeground(new Color(150,150,150));
widthField.setFont(new Font("Arial",Font.PLAIN,12));
widthField.setForeground(new Color(150,150,150));
// using shapegroup to organize the JRadioButtons
shapeGroup.add(squareButton);
shapeGroup.add(ovalButton);
shapeGroup.add(rectangleButton);
shapeGroup.add(triangleButton);
// using colorgroup to organize the color radiobuttons
colorGroup.add(redButton);
colorGroup.add(blueButton);
colorGroup.add(greenButton);
colorGroup.add(yellowButton);
// add the shape buttons to the panel so they appear in a square form
shapePanel.add(squareButton);
shapePanel.add(ovalButton);
shapePanel.add(rectangleButton);
shapePanel.add(triangleButton);
// adding color buttons to the color panel
colorPanel.add(redButton);
colorPanel.add(blueButton);
colorPanel.add(greenButton);
colorPanel.add(yellowButton);
// adding jbuttons
buttonPanel.add(drawButton);
buttonPanel.add(animateButton);
// adding textfields to the textPanel
textPanel.add(lengthField);
textPanel.add(widthField);
dPanel = new drawPanel();
dPanel.setPreferredSize(new Dimension(500,300));
// adding panels to the applet
add(shapePanel);
add(colorPanel);
add(buttonPanel);
add(textPanel);
add(dPanel);
// adding focus listener to lengthField and widthField
lengthField.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent e) {
lengthField.setText("");
lengthField.setForeground(Color.black);
}
public void focusLost(FocusEvent e) {}
});
widthField.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent e) {
widthField.setText("");
widthField.setForeground(Color.black);
}
public void focusLost(FocusEvent e) {}
});
drawButton.addActionListener(new drawListener());
}
// when the person presses paint, this will be executed to paint the specific shape, color with the width and length
class drawListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
int mylength = 5;
int mywidth = 5;
try {
mylength = Integer.parseInt(lengthField.getText());;
mywidth = Integer.parseInt(widthField.getText());;
}catch(Exception ex) {
JOptionPane.showMessageDialog(null,""+ex,"",JOptionPane.ERROR_MESSAGE);
}
if((mylength > 200 || mylength < 5)) {
JOptionPane.showMessageDialog(null, "Please make sure the number is above 5 and less than 200",
"Invalid length message", JOptionPane.ERROR_MESSAGE);
}else if((mywidth > 200 || mywidth < 5)) {
JOptionPane.showMessageDialog(null, "Please make sure the number is above 5 and less than 200",
"Invalid width message", JOptionPane.ERROR_MESSAGE);
}else {
length = mylength;
width = mywidth;
// checking which color button is selected
if(redButton.isSelected()) {
color = Color.RED;
}else if(blueButton.isSelected()) {
color = Color.BLUE;
}else if(greenButton.isSelected()) {
color = Color.GREEN;
}else if(yellowButton.isSelected()) {
color = Color.YELLOW;
}
// checking which shape has been selected
if(rectangleButton.isSelected()) {
shape = "rectangle";
}else if(triangleButton.isSelected()) {
shape = "triangle";
}else if(ovalButton.isSelected()) {
shape = "oval";
}else if(squareButton.isSelected()) {
shape = "square";
}
//System.out.printf("%3d %3d %s %s \n",length,width,shape,color);
}
}
}
// This will be used to do the painting
class drawPanel extends JPanel {
private static final long serialVersionUID = 1L;
//Paint Method
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.black);
g2.drawString("My awesome string", 200, 200);
}
}
}
Related
This project revolves around a game that is a variation of TicTacToe called SOS. One of the requirements is that the game grid needs to have two size options. The smaller grid is 5x5 and the larger is 8x8.
My goal is to have the grid size change based off which radio button is selected. In my code below I have a commented out method to change the GRID_SIZE variable based off which radio button is selected. But it does not work where it is currently and I am struggling to come up with the solution. The other problem related to the grid size changing that I think I'll have is, I do not believe the way I create the grid now will allow for it to change live as the radio buttons are pushed.
I will need to be keeping track of what gets played in each cell of the grid (whether a player is placing an S or an O) So my thought is maybe there is a better way to create the grid for both the GUI and as a storage method for the moves played.
This project is my first java project and first GUI project of this depth. It is also the major project for one of my last classes to graduate so I'm taking this seriously and could really use the help. I know my code is probably not great, I'm here to improve so any help is welcomed.
package practice;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
#SuppressWarnings({ "serial", "unused"})
public class SOS_GUI extends JFrame {
public int GRID_SIZE = 8;
public Grid grid;
public SOS_GUI() {
GameBoard();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setTitle("SOS Practice");
this.setLocationRelativeTo(null);
setVisible(true);
}
public void GameBoard(){
// CONTENT PANE FOR HOLDING ALL GUI COMPONENTS
Container ContentPane = getContentPane();
// PANEL FOR GAME GRID
JPanel gameBoardCanvas = new JPanel();
gameBoardCanvas.setLayout(new GridLayout(GRID_SIZE, GRID_SIZE));
for (int x = 0; x < GRID_SIZE; x++) {
for (int y = 0; y < GRID_SIZE; y++) {
final Grid cell = new Grid(x, y);
gameBoardCanvas.add(cell);
}
}
// FOUR PANELS SURROUNDING GAME GRID
JPanel TopPanel = new JPanel();
JPanel BottomPanel = new JPanel();
JPanel LeftPanel = new JPanel();
JPanel RightPanel = new JPanel();
JLabel SpacerLabel = new JLabel(" || ");
// GAME MODE OOPTIONS - SIMPLE OR GENERAL
JLabel GameModeLabel = new JLabel("Game Mode :");
JRadioButton SimpleGameButton = new JRadioButton("Simple", true);
JRadioButton GeneralGameButton = new JRadioButton("General");
ButtonGroup GameModeButtons = new ButtonGroup();
GameModeButtons.add(SimpleGameButton);
GameModeButtons.add(GeneralGameButton);
// BOARD SIZE BUTTONS - SMALL(5X5) OR LARGE(8X8)
JLabel SizeOptionLabel = new JLabel("Board Size :");
JRadioButton SmallGridButton = new JRadioButton("Small", true);
JRadioButton LargeGridButton = new JRadioButton("Large");
ButtonGroup GridSizeButtons = new ButtonGroup();
GridSizeButtons.add(SmallGridButton);
GridSizeButtons.add(LargeGridButton);
// PLAY LETTER SETTINGS
JRadioButton PlayS_Button = new JRadioButton("S", true);
JRadioButton PlayO_Button = new JRadioButton("O");
ButtonGroup PlayLetterButtons = new ButtonGroup();
PlayLetterButtons.add(PlayS_Button);
PlayLetterButtons.add(PlayO_Button);
// BLUE PLAYER SETTINGS
JLabel BluePlayerLabel = new JLabel("Blue Player");
JRadioButton BlueHumanButton = new JRadioButton("Human", true);
JRadioButton BlueComputerButton = new JRadioButton("Computer");
ButtonGroup BluePlayerButtons = new ButtonGroup();
BluePlayerButtons.add(BlueHumanButton);
BluePlayerButtons.add(BlueComputerButton);
// RED PLAYER SETTINGS
JLabel RedPlayerLabel = new JLabel("Red Player");
JRadioButton RedHumanButton = new JRadioButton("Human");
JRadioButton RedComputerButton = new JRadioButton("Computer", true);
ButtonGroup RedPlayerButtons = new ButtonGroup();
RedPlayerButtons.add(RedHumanButton);
RedPlayerButtons.add(RedComputerButton);
// ADDING COMPONENTS TO TOP PANEL
TopPanel.add(GameModeLabel);
TopPanel.add(SimpleGameButton);
TopPanel.add(GeneralGameButton);
TopPanel.add(SpacerLabel);
TopPanel.add(SizeOptionLabel);
TopPanel.add(SmallGridButton);
TopPanel.add(LargeGridButton);
// ADDING COMPONENTS TO BOTTOM PANEL
BottomPanel.add(PlayS_Button);
BottomPanel.add(PlayO_Button);
// ADDING COMPONENTS TO LEFT PANEL
LeftPanel.add(BluePlayerLabel);
LeftPanel.add(BlueHumanButton);
LeftPanel.add(BlueComputerButton);
// ADDING COMPONENTS TO RIGHT PANEL
RightPanel.add(RedPlayerLabel);
RightPanel.add(RedHumanButton);
RightPanel.add(RedComputerButton);
// ADDING PANELS TO CONTENT PANE
ContentPane.setLayout(new BorderLayout());
ContentPane.add(TopPanel, BorderLayout.NORTH);
ContentPane.add(BottomPanel, BorderLayout.SOUTH);
ContentPane.add(LeftPanel, BorderLayout.WEST);
ContentPane.add(RightPanel, BorderLayout.EAST);
ContentPane.add(gameBoardCanvas, BorderLayout.CENTER);
TopPanel.setPreferredSize(new Dimension(50, 50));
BottomPanel.setPreferredSize(new Dimension(50, 50));
LeftPanel.setPreferredSize(new Dimension(100, 100));
RightPanel.setPreferredSize(new Dimension(100, 100));
ContentPane.setPreferredSize(new Dimension(550, 500));
}
// CLASS SETTING UP HOW THE GRID WILL BE CREATED
class Grid extends JPanel {
public static final int CELL_SIZE = 1;
private int xPos;
private int yPos;
public JLabel gridLabel;
public Grid (int x, int y) {
xPos = x;
yPos = y;
gridLabel = new JLabel("");
gridLabel.setFont(new Font("Serif", Font.BOLD, 40));
add(gridLabel);
setOpaque(true);
setLayout(new FlowLayout());
setBorder(BorderFactory.createBevelBorder(CELL_SIZE));
setBackground(new Color(200, 200, 200));
setPreferredSize(new Dimension(CELL_SIZE, CELL_SIZE));
}
}
/* POSSIBLE FUNCTION TO SET GRID_SIZE BASED OFF RADIO BUTTON INPUT? DOESNT WORK HERE
public getGridSize() {
if (GameBoard().SmallGridButton.isSelected() == true) {
GRID_SIZE = 5;
}
else if (GameBoard().LargeGridButton.isSelected() == true) {
GRID_SIZE = 8;
}
return GRID_SIZE;
}
*/
public static void main(String[] args) {
new SOS_GUI();
}
}
screenshot of the smaller 5x5 grid
screenshot of larger 8x8 grid
Again, I suggest that if you want to use components as your grid cell, that you either swap views (JPanels) using a CardLayout, or you swap out the grid cells when a JRadioButton is pressed.
I suggest:
Adding an ActionListener to the JRadioButton to be notified when it is pressed.
If you will swap components, then create a JPanel to hold the grid cells, say called gridHolder, and remove all components when the button is pressed.
Then add a new GridLayout layout manager to this JPanel, with constraints set depending on whih JRadioButton has been pressed.
Then re-adding grid cell components to this holder JPanel
Then relaying out all components in the GUI and resizing it by calling pack() on the top-level window, here a JFrame.
In the example below, I use JLabels to hold the grid cells since it is trivial to add text to these.
I store the row and column of each grid cell using the .putClientProperty(...) method and likewise can retrieve values using the .getClientProperty(...) method.
I call createGrid(...) in the constructor to create the grid with the default, small, size.
I call the same method whenever a JRadioButton has been pressed.
For example:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
import javax.swing.border.BevelBorder;
#SuppressWarnings("serial")
public class SosGrid2 extends JPanel {
private static final int SMALL_SIZE = 5;
private static final int LARGE_SIZE = 8;
private static final String[] SIZES = { "Small", "Large" };
private static final Dimension CELL_SIZE = new Dimension(60, 60);
private static final Color GRID_BG = new Color(200, 200, 200);
private static final String ROW = "row";
private static final String COL = "col";
private JPanel gridHolder = new JPanel();
private ButtonGroup gridSizeGroup = new ButtonGroup();
public SosGrid2() {
JPanel radioButtonPanel = new JPanel();
for (String size : SIZES) {
JRadioButton radioButton = new JRadioButton(size);
radioButton.setSelected(size.equals(SIZES[0]));
radioButton.setActionCommand(size);
gridSizeGroup.add(radioButton);
radioButtonPanel.add(radioButton);
radioButton.addActionListener(e -> radioListener());
}
createGrid(SMALL_SIZE);
setLayout(new BorderLayout());
add(gridHolder);
add(radioButtonPanel, BorderLayout.PAGE_END);
}
private void createGrid(int gridSize) {
gridHolder.removeAll();
gridHolder.setLayout(new GridLayout(gridSize, gridSize));
for (int row = 0; row < gridSize; row++) {
for (int col = 0; col < gridSize; col++) {
JLabel gridCell = createGridCell(row, col);
gridHolder.add(gridCell);
}
}
}
// factory method to create grid cell JLabels.
private JLabel createGridCell(int row, int col) {
JLabel label = new JLabel("", SwingConstants.CENTER);
label.setFont(label.getFont().deriveFont(Font.BOLD, 32f));
label.setOpaque(true);
label.setBackground(GRID_BG);
label.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
label.setPreferredSize(CELL_SIZE);
label.putClientProperty(ROW, row);
label.putClientProperty(COL, col);
label.addMouseListener(new MyMouseListener());
return label;
}
private class MyMouseListener extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
JLabel gridCell = (JLabel) e.getSource();
int row = (int) gridCell.getClientProperty(ROW);
int col = (int) gridCell.getClientProperty(COL);
String message = String.format("Row: %d, Col: %d", row, col);
String title = "Cell Pressed";
int type = JOptionPane.PLAIN_MESSAGE;
JOptionPane.showMessageDialog(SosGrid2.this, message, title, type);
String text = gridCell.getText();
if (text.isEmpty()) {
gridCell.setText("X");
} else {
gridCell.setText("");
}
}
}
private void radioListener() {
ButtonModel btnModel = gridSizeGroup.getSelection();
if (btnModel != null) {
int gridSize = btnModel.getActionCommand().equals(SIZES[0]) ? SMALL_SIZE : LARGE_SIZE;
createGrid(gridSize);
Window jframe = SwingUtilities.getWindowAncestor(this);
jframe.pack();
jframe.setLocationRelativeTo(null);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
SosGrid2 mainPanel = new SosGrid2();
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
as you can see in the image above, I've a tabbed pane. On the tab header I've a JLabel (Tab Test) and a JButton (X). They are placed next to each other but I want them to have a small gap to look natural.
I've tried with a Box but it has the same background has the text making it not look natural as well. The Box has no setBorders method.
Here's how it look like with a Box:
Here's my code:
System.out.println("NewTableEvent!!!!");
final String tittle = table.getTabName();
JButton jButtonClose = new JButton("X");
jButtonClose.setBorderPainted(false);
jButtonClose.setBorder(null);
JPanel tabComponent = new JPanel(new BorderLayout());
tabComponent.add(new JLabel(tittle), BorderLayout.WEST);
tabComponent.setToolTipText("Close this tab.");
Component box = Box.createRigidArea(new Dimension(25,0));
tabComponent.add(box, BorderLayout.CENTER);
tabComponent.add(jButtonClose, BorderLayout.EAST);
// rightTabbedPane.addTab(null, table.getTable());
rightTabbedPane.addTab(null, new JPanel());
// Get total tabs
final int totalTabs = rightTabbedPane.getComponentCount();
System.out.println("Total tabs: " + totalTabs);
// Set the custom tab component
rightTabbedPane.setTabComponentAt(0, tabComponent);
So, how can I make space the JLabel and JButton and keep the background from that distance neutral?
I wasn't able to test it, but I believe you would just have to tell the box to not be opaque before you add it to the tabComponent:
box.setOpaque(false);
Hopefully, that should work for you.
EDIT
You may be able to set borders around the label and button to accomplish this:
JLabel label = new JLabel(tittle);
tabComponent.add(label);
//add more space between the label and the button
label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
tabComponent.add(jButtonClose);
Demo at: http://docs.oracle.com/javase/tutorial/uiswing/components/tabbedpane.html
Thanks to #Gavin Markee, I came up with this solution:
First, create this new class (It's the exact same class given in the example from Gavin MArkee's link, I'm just posting it here in case it is romoved in the future):
public class ButtonTabComponent extends JPanel {
private final JTabbedPane pane;
public ButtonTabComponent(final JTabbedPane pane) {
// Unset default FlowLayout' gaps
super(new FlowLayout(FlowLayout.LEFT, 0, 0));
if (pane == null) {
throw new NullPointerException("TabbedPane is null");
}
this.pane = pane;
setOpaque(false);
//make JLabel read titles from JTabbedPane
JLabel label = new JLabel() {
#Override
public String getText() {
int i = pane.indexOfTabComponent(ButtonTabComponent.this);
if (i != -1) {
return pane.getTitleAt(i);
}
return null;
}
};
add(label);
//add more space between the label and the button
label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
//tab button
JButton button = new TabButton();
add(button);
//add more space to the top of the component
setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
}
private class TabButton extends JButton implements ActionListener {
public TabButton() {
int size = 17;
setPreferredSize(new Dimension(size, size));
setToolTipText("close this tab");
//Make the button looks the same for all Laf's
setUI(new BasicButtonUI());
//Make it transparent
setContentAreaFilled(false);
//No need to be focusable
setFocusable(false);
setBorder(BorderFactory.createEtchedBorder());
setBorderPainted(false);
//Making nice rollover effect
//we use the same listener for all buttons
addMouseListener(buttonMouseListener);
setRolloverEnabled(true);
//Close the proper tab by clicking the button
addActionListener(this);
}
#Override
public void actionPerformed(ActionEvent e) {
int i = pane.indexOfTabComponent(ButtonTabComponent.this);
if (i != -1) {
pane.remove(i);
}
}
//we don't want to update UI for this button
#Override
public void updateUI() {
}
//paint the cross
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
//shift the image for pressed buttons
if (getModel().isPressed()) {
g2.translate(1, 1);
}
g2.setStroke(new BasicStroke(2));
g2.setColor(Color.BLACK);
if (getModel().isRollover()) {
g2.setColor(Color.MAGENTA);
}
int delta = 6;
g2.drawLine(delta, delta, getWidth() - delta - 1, getHeight() - delta - 1);
g2.drawLine(getWidth() - delta - 1, delta, delta, getHeight() - delta - 1);
g2.dispose();
}
}
private final static MouseListener buttonMouseListener = new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent e) {
Component component = e.getComponent();
if (component instanceof AbstractButton) {
AbstractButton button = (AbstractButton) component;
button.setBorderPainted(true);
}
}
#Override
public void mouseExited(MouseEvent e) {
Component component = e.getComponent();
if (component instanceof AbstractButton) {
AbstractButton button = (AbstractButton) component;
button.setBorderPainted(false);
}
}
};
}
And then when you create your tabe you just have to:
tabbedPane.addTab(myTabTitle, myTable);
tabbedPane.setTabComponentAt(tabIndex, new ButtonTabComponent(tabbedPane));
i'm trying to add a slider to my GUI, but it won't show up, i'm new to java so if you could help it would be much appreciated! I'm not sure how to add the slider to the main grid, at the moment it dosn't appear.
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
import javax.swing.*;
public class Grid extends JFrame
{
public void Slider()
{
setLayout(new FlowLayout());
JSlider slider;
JLabel label;
slider = new JSlider(JSlider.VERTICAL, 0, 20, 0);
slider.setMajorTickSpacing(5);
slider.setPaintTicks(true);
add(slider);
label = new JLabel ("Number of lifeforms: 0");
add(label);
}
public static void main (String args[])
{
JFrame Grid = new JFrame();
Grid.setSize(800,600);
Grid.setTitle("Artificial life simulator");
Grid.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
String rows = JOptionPane.showInputDialog("How many rows does the grid have?");
int row = Integer.parseInt(rows);
String columns = JOptionPane.showInputDialog("How many columns does the grid have?");
int col = Integer.parseInt(columns);
JOptionPane.showConfirmDialog(null, "Are these the correct demensions: "
+row+" x "+col+ "?",
"Yes or No", JOptionPane.YES_NO_OPTION);
Container pane = Grid.getContentPane();
pane.setLayout(new GridLayout(row,col));
Color square;
for (int x = 1; x <=(row*col); x++)
{
int altr = 0;
altr = (x-1) % col;
altr += (x-1) / col;
if (altr % 2 == 0)
{
square = Color.white;
}
else
{
square = Color.black;
}
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(800/row, 600/col));
panel.setBackground(square);
pane.add(panel);
}
Grid.setVisible(true);
}
}
Note several changes to your example:
The default layout of JFrame is BorerLayout; a vertical slider goes well in EAST.
The slider() method returns a JSlider; the label can go in one of the three remaining BorerLayout areas.
Override getPreferredSize() to define the size of the rendering pane.
TODO: See also Initial Threads.
As tested:
import java.awt.*;
import javax.swing.*;
public class Grid extends JFrame {
private static JSlider slider() {
JSlider slider;
slider = new JSlider(JSlider.VERTICAL, 0, 20, 0);
slider.setMajorTickSpacing(5);
slider.setPaintTicks(true);
return slider;
}
public static void main(String args[]) {
JFrame grid = new JFrame();
grid.setSize(800, 600);
grid.setTitle("Artificial life simulator");
grid.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
int row = 3;
int col = 3;
JPanel pane = new JPanel(){
#Override
public Dimension getPreferredSize() {
return new Dimension(320, 240);
}
};
pane.setLayout(new GridLayout(row, col));
Color square;
for (int x = 1; x <= (row * col); x++) {
int altr = 0;
altr = (x - 1) % col;
altr += (x - 1) / col;
if (altr % 2 == 0) {
square = Color.white;
} else {
square = Color.black;
}
JPanel panel = new JPanel(new GridLayout());
panel.setBackground(square);
pane.add(panel);
}
grid.add(pane);
grid.add(slider(), BorderLayout.EAST);
grid.pack();
grid.setVisible(true);
}
}
I am using Swing and AWT (for the listeners) to make a small program. I have a problem concerning getting the size of my JPanel (the class named Chess).
My Layout:
public class Main extends JFrame implements MouseListener, ActionListener{
Chess chessPanel = new Chess ();
JButton newGameButton = new JButton ("New Game");
JButton loadGameButton = new JButton ("Load Game");
JButton saveGameButton = new JButton ("Save Game");
JButton exitButton = new JButton ("Exit");
public static void main (String [] args) {
new Main();
}
Main () {
super ("Chess");
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
setSize(dim);
setLocation(0,0);
setUndecorated(true);
chessPanel.addMouseListener(this);
add(chessPanel, BorderLayout.CENTER);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout());
newGameButton.addActionListener(this);
loadGameButton.addActionListener(this);
saveGameButton.addActionListener(this);
exitButton.addActionListener(this);
buttonPanel.add(newGameButton);
buttonPanel.add(loadGameButton);
buttonPanel.add(saveGameButton);
buttonPanel.add(exitButton);
add(buttonPanel, BorderLayout.SOUTH);
setVisible(true);
}
// ... Code ...
}
As you can see by the code, I have one JPanel in the CENTER, which takes nearly all the screen. In the bottom I have another JPanel (SOUTH), which has a row of buttons.
What I need is the size that the JPanel in the CENTER takes. When I call the getWidth(), getHeight() or getBounds() methods inherited from JPanel, they all return 0, because of the BorderLayout.
Any idea how to get the real values?
PS: The screen always takes up the entire screen, and will never be resized, if that helps.
You're likely calling getWidth before the JPanel has been rendered, and so it will be 0. The solution is to get the size after rendering, for instance after pack() or setVisible(true) has been called on the root container that holds this JPanel.
Also, I recommend against calling setSize() on anything since most of the standard layout managers observe the preferred size of a component, not the size, and when you call pack() telling the layout managers to do their thing, the set sizes are usually ignored. You may want to make your JPanel that is in the center set its own size by overriding its setPreferredSize method if it needs to be a certain size. Then let the JFrame and its held containers set the bet fit size based on the their layout managers when you call pack.
e.g.,
import java.awt.*;
import javax.swing.*;
public class Main extends JFrame {
Chess chessPanel = new Chess();
JButton newGameButton = new JButton("New Game");
JButton loadGameButton = new JButton("Load Game");
JButton saveGameButton = new JButton("Save Game");
JButton exitButton = new JButton("Exit");
public static void main(String[] args) {
new Main();
}
Main() {
super("Chess");
add(chessPanel, BorderLayout.CENTER);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout());
buttonPanel.add(newGameButton);
buttonPanel.add(loadGameButton);
buttonPanel.add(saveGameButton);
buttonPanel.add(exitButton);
System.out.printf("chessPanel Size before rendering: %s%n", chessPanel.getSize());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(buttonPanel, BorderLayout.SOUTH);
pack();
System.out.printf("chessPanel Size after rendering: %s%n", chessPanel.getSize());
setLocationRelativeTo(null);
setVisible(true);
}
// ... Code ...
}
#SuppressWarnings("serial")
class Chess extends JPanel {
private static final int CHESS_WIDTH = 600;
private static final int CHESS_HEIGHT = CHESS_WIDTH;
private static final int MAX_ROW = 8;
private static final int MAX_COL = 8;
private static final Color LIGHT_COLOR = new Color(240, 190, 40);
private static final Color DARK_COLOR = new Color(180, 50, 0);
#Override
public Dimension getPreferredSize() {
return new Dimension(CHESS_WIDTH, CHESS_HEIGHT);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int panelWidth = getWidth();
int panelHeight = getHeight();
int sqrWidth = panelWidth / MAX_ROW;
int sqrHeight = panelHeight / MAX_COL;
for (int row = 0; row < MAX_ROW; row++) {
for (int col = 0; col < MAX_COL; col++) {
Color c = (row % 2 == col % 2) ? LIGHT_COLOR : DARK_COLOR;
g.setColor(c);
int x = (row * panelWidth) / MAX_ROW;
int y = (col * panelHeight) / MAX_COL;
g.fillRect(x, y, sqrWidth, sqrHeight);
}
}
}
}
This question is related to my previous question How to generate Cartesian Coordinate (x,y) from GridBaglayout?
I have successfully get the coordinate of each pictures, however when I checked the coordinate through (System.out.println) and the placement of the images on the screen, it seems to be wrong. e.g. if on the screen it was obvious that the x point of the first picture is on cell 2 which is on coordinate of 20, but the program shows x=1.
Here is part of the code:
public Grid (){
setPreferredSize(new Dimension(600,600));
....
setLayout(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
gc.weightx = 1d;
gc.weighty = 1d;
gc.insets = new Insets(0, 0, 0, 0);//top, left, bottom, and right
gc.fill = GridBagConstraints.BOTH;
JLabel[][] label = new JLabel[ROWS][COLS];
Random rand = new Random();
// fill the panel with labels
for (int i=0;i<IMAGES;i++){
ImageIcon icon = createImageIcon("myPics.jpg");
int r, c;
do{
//pick random cell which is empty
r = (int)Math.floor(Math.random() * ROWS);
c = (int)Math.floor(Math.random() * COLS);
} while (label[r][c]!=null);
//randomly scale the images
int x = rand.nextInt(50)+30;
int y = rand.nextInt(50)+30;
Image image = icon.getImage().getScaledInstance(x,y, Image.SCALE_SMOOTH);
icon.setImage(image);
JLabel lbl = new JLabel(icon); // Instantiate GUI components
gc.gridx = r;
gc.gridy = c;
add(lbl, gc); //add(component, constraintObj);
label[r][c] = lbl;
}
I checked the coordinate through this code:
Component[] components = getComponents();
for (Component component : components) {
System.out.println(component.getBounds());
}
You can use SwingUtilities convertPointToScreen() and convertPointFromScreen() to convert between screen and component coordinates.
Addendum: Here's a simple example I used when trying to understand how components move and resize under the influence of a layout manager.
public class MyPanel extends JPanel {
public MyPanel() {
super(new GridLayout(4, 4));
for (int i = 0; i < 16; i++) {
JPanel panel = new JPanel(new GridLayout());
panel.add(new CenterLabel());
this.add(panel);
}
}
private static void create() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new MyPanel());
f.pack();
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
create();
}
});
}
private static class CenterLabel extends JLabel {
public CenterLabel() {
this.setHorizontalAlignment(JLabel.CENTER);
this.setVerticalAlignment(JLabel.CENTER);
this.setOpaque(true);
this.setBackground(Color.lightGray);
this.setBorder(BorderFactory.createLineBorder(Color.blue));
this.setPreferredSize(new Dimension(160, 100));
this.addComponentListener(new ComponentAdapter() {
#Override
public void componentResized(ComponentEvent e) {
int w = e.getComponent().getWidth();
int h = e.getComponent().getHeight();
CenterLabel.this.setText("[" + w/2 + "\u253C" + h/2 + "]");
}
});
}
}
}
if on the screen it was obvious that
the x point of the first picture is on
cell 2 which is on coordinate of 20,
but the program shows x=1.
The first image will have x/y coordinates of 0/0. The second images will have coordinates of 1/0. The X/Y values of offset from 0. Is that what you are talking about?
Or is your listener added to the image not the panel in which case you need to convert the image coordinates to the panel coordinates. Check our the SwingUtilities class for methods to do this.
If you need more help post your SSCCE.