How to open new applet window from a applet - java

how can i open a new applet window from a applet itself?

To open a new Java window (JFrame) from an applet, see the following extract from the Java tutorial:
//1. Create the frame.
JFrame frame = new JFrame("FrameDemo");
//2. Optional: What happens when the frame closes?
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//3. Create components and put them in the frame.
//...create emptyLabel...
frame.getContentPane().add(emptyLabel, BorderLayout.CENTER);
//4. Size the frame.
frame.pack();
//5. Show it.
frame.setVisible(true);
To open a new browser window which also contains an applet showDocument(URL, "_blank"):
URL url = new URL(getCodeBase().getProtocol(),
getCodeBase().getHost(),
getCodeBase().getPort(),
"/next.html");
getAppletContext().showDocument(url, "_blank");

package com.ashok.test;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
public class ChessBoardWithColumnsAndRows {
private final JPanel gui = new JPanel(new BorderLayout(3, 3));
private JButton[][] chessBoardSquares = new JButton[8][8];
private JPanel chessBoard;
private final JLabel message = new JLabel(
"Chess Champ is ready to play!");
private static final String COLS = "ABCDEFGH";
ChessBoardWithColumnsAndRows() {
initializeGui();
}
public final void initializeGui() {
// set up the main GUI
gui.setBorder(new EmptyBorder(5, 5, 5, 5));
JToolBar tools = new JToolBar();
tools.setFloatable(false);
gui.add(tools, BorderLayout.PAGE_START);
tools.add(new JButton("New")); // TODO - add functionality!
tools.add(new JButton("Save")); // TODO - add functionality!
tools.add(new JButton("Restore")); // TODO - add functionality!
tools.addSeparator();
tools.add(new JButton("Resign")); // TODO - add functionality!
tools.addSeparator();
tools.add(message);
gui.add(new JLabel("?"), BorderLayout.LINE_START);
chessBoard = new JPanel(new GridLayout(0, 9));
chessBoard.setBorder(new LineBorder(Color.BLACK));
gui.add(chessBoard);
// create the chess board squares
Insets buttonMargin = new Insets(0,0,0,0);
for (int ii = 0; ii < chessBoardSquares.length; ii++) {
for (int jj = 0; jj < chessBoardSquares[ii].length; jj++) {
JButton b = new JButton();
b.setMargin(buttonMargin);
// our chess pieces are 64x64 px in size, so we'll
// 'fill this in' using a transparent icon..
ImageIcon icon = new ImageIcon(
new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB));
b.setIcon(icon);
if ((jj % 2 == 1 && ii % 2 == 1)
//) {
|| (jj % 2 == 0 && ii % 2 == 0)) {
b.setBackground(Color.WHITE);
} else {
b.setBackground(Color.BLACK);
}
chessBoardSquares[jj][ii] = b;
}
}
//fill the chess board
chessBoard.add(new JLabel(""));
// fill the top row
for (int ii = 0; ii < 8; ii++) {
chessBoard.add(
new JLabel(COLS.substring(ii, ii + 1),
SwingConstants.CENTER));
}
// fill the black non-pawn piece row
for (int ii = 0; ii < 8; ii++) {
for (int jj = 0; jj < 8; jj++) {
switch (jj) {
case 0:
chessBoard.add(new JLabel("" + (ii + 1),
SwingConstants.CENTER));
default:
chessBoard.add(chessBoardSquares[jj][ii]);
}
}
}
}
public final JComponent getChessBoard() {
return chessBoard;
}
public final JComponent getGui() {
return gui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
ChessBoardWithColumnsAndRows cb =
new ChessBoardWithColumnsAndRows();
JFrame f = new JFrame("ChessChamp");
f.add(cb.getGui());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
// ensures the frame is the minimum size it needs to be
// in order display the components within it
f.pack();
// ensures the minimum size is enforced.
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}

Related

Java Swing graphics resolution and dimensions distorted in JDK10

I've updated the compiler version for a basic Swing project from JDK1.8 to JDK10. This has resulted in poorer image resolution, and sizes/dimensions of JPanels now appear different. See screenshots for J8 vs J10:
Java 8:
Java 10:
Below is the entire app code:
package com.nickjwhite.test;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class App {
//UI objects
private JFrame frame;
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
new App();
}
public App() {
try {
//
//
//Initialise Parent Frame
//
//
setFrame(new JFrame());
getFrame().setSize(1200,800); // Dimensions of non-Maximised frame
getFrame().setTitle("Test App");
getFrame().setLocationRelativeTo(null); // Centre the frame
getFrame().setExtendedState(JFrame.MAXIMIZED_BOTH); // Maximise the frame on launch
getFrame().setIconImage(ImageIO.read(getClass().getClassLoader().getResourceAsStream("test.jpg")));
getFrame().setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Kill process if window closed
getFrame().setVisible(true);
//
//
//Main content panel
//
//
contentPane = new JPanel(new GridBagLayout());
contentPane.setBackground(Color.decode("#2e3131"));
getFrame().setContentPane(contentPane);
//
//
//MenuPanel
//
//
JPanel menuPanel = new JPanel();
//Initialise Menu
// Title Background
//
JPanel menuTitleBg = new JPanel();
menuTitleBg.setLayout(new GridBagLayout());
menuTitleBg.setBackground(Color.decode("#d5b8ff"));
GridBagConstraints menuTitleBg_constraints = new GridBagConstraints();
menuTitleBg_constraints.fill = GridBagConstraints.BOTH;
menuTitleBg_constraints.gridx = 0;
menuTitleBg_constraints.gridy = 0;
menuTitleBg_constraints.weightx = 1;
menuTitleBg_constraints.weighty = 0;
menuPanel.add(menuTitleBg, menuTitleBg_constraints);
JLabel testImage = new JLabel();
GridBagConstraints testImage_constraints = new GridBagConstraints();
testImage_constraints.insets = new Insets(10, 10, 10, 10);
testImage_constraints.gridx = 0;
testImage_constraints.gridy = 0;
testImage.setSize(new Dimension(80,80));
testImage.setOpaque(false);
menuTitleBg.add(testImage,testImage_constraints);
try {
BufferedImage img = ImageIO.read(App.class.getClassLoader().getResourceAsStream("test.jpg"));
Image dimg = img.getScaledInstance(testImage.getWidth(), testImage.getHeight(), Image.SCALE_SMOOTH);
testImage.setIcon(new ImageIcon(dimg));
} catch (IOException e) {
e.printStackTrace();
}
menuPanel.setLayout(new GridBagLayout());
menuPanel.setBackground(Color.decode("#9b59b6"));
menuPanel.setPreferredSize(new Dimension(400, (int) (contentPane.getPreferredSize().height)));
menuPanel.setMinimumSize(new Dimension(400,10));
GridBagConstraints gbc_panel = new GridBagConstraints();
gbc_panel.fill = GridBagConstraints.BOTH;
gbc_panel.gridx = 0;
gbc_panel.gridy = 0;
gbc_panel.weightx = 0;
gbc_panel.weighty = 1;
JScrollPane menuScrollPane = new JScrollPane(menuPanel);
menuScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
menuScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
menuScrollPane.setPreferredSize(new Dimension(400, (int) (contentPane.getPreferredSize().height)));
contentPane.add(menuScrollPane , gbc_panel);
//
//
//Action Window Panel
//
//
JPanel actionWindow = new JPanel();
actionWindow.setLayout(new GridBagLayout());
actionWindow.setBackground(Color.decode("#2e3131"));
GridBagConstraints gbc_actionWindow = new GridBagConstraints();
gbc_actionWindow.anchor = GridBagConstraints.EAST;
gbc_actionWindow.fill = GridBagConstraints.BOTH;
gbc_actionWindow.gridx = 1;
gbc_actionWindow.gridy = 0;
gbc_actionWindow.weightx = 1;
gbc_actionWindow.weighty = 1;
contentPane.add(actionWindow, gbc_actionWindow);
} catch (IOException e) {
e.printStackTrace();
}
}
public JFrame getFrame() {
return frame;
}
public void setFrame(JFrame frame) {
this.frame = frame;
}
}
I need to continue compiling with JDK10 for this project, but need the GUI to reflect the JDK8 output, preferably acheiving this without having to adjust the menuPanel Preferred Size, or the testImage dimenstions.
Anyone know what's caused this?

In a 2D array of JButtons, how to change lines?

I am trying to create a 2D array of buttons but the buttons I created are all in the same line. I can change lines in 2D arrays of int and float by using System.out.println(). What should I so for buttons? (line 67 to 75)
As well, I don't know how to create actionListeners for buttons in a loop. Should I create a method for acctionLisener? Do they share the same action listener?
import java.awt.*;
import javax.swing.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JInternalFrame;
public class Hanoi {
private JFrame frame;
JButton[][] buttons= new JButton[3][3];
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Hanoi window = new Hanoi();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Hanoi() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 901, 696);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panelone = new JPanel();
frame.getContentPane().add(panelone, BorderLayout.CENTER);
panelone.setBackground(Color.WHITE);
GridBagLayout gbl_panelone = new GridBagLayout();
gbl_panelone.columnWidths = new int[]{0};
gbl_panelone.rowHeights = new int[]{0};
gbl_panelone.columnWeights = new double[]{Double.MIN_VALUE};
gbl_panelone.rowWeights = new double[]{Double.MIN_VALUE};
panelone.setLayout(gbl_panelone);
JPanel paneltwo = new JPanel();
frame.getContentPane().add(paneltwo, BorderLayout.NORTH);
paneltwo.setBackground(Color.WHITE);
JLabel lblFunHanoiTower = new JLabel("Fun Hanoi Tower");
lblFunHanoiTower.setForeground(Color.BLACK);
lblFunHanoiTower.setBackground(SystemColor.activeCaption);
lblFunHanoiTower.setFont(new Font("Viner Hand ITC", Font.PLAIN, 36));
paneltwo.add(lblFunHanoiTower);
//JButton[][] buttons = new JButton[3][3];
for(int row = 0; row < buttons.length ; row++) {
for(int col= 0; col < buttons[0].length ;col++) {
buttons[row][col] = new JButton(String.valueOf((row+3)+(col*3)));
buttons[row][col].setFont(new Font("Tempus Sans ITC", Font.BOLD, 16));
buttons[row][col].setBackground(SystemColor.controlHighlight);
buttons[row][col].setSize(66, 66);
panelone.add(buttons[row][col]);
}
}
}
}
Rather than modify your code, I have provided an example of GridLayout.
GridLayout divides the area of the JPanel into a grid, i.e. a table of rows and columns, where each "cell" in the grid can contain one component and each cell has the same size. Here is a complete, compilable and runnable example.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
public class Hanoi implements Runnable {
#Override // java.lang.Runnable
public void run() {
showGui();
}
private JPanel createGridPanel() {
// Number of rows will be calculated depending on total number
// of components added but each row will contain no more than
// three components.
GridLayout gridLayout = new GridLayout(0, 3);
JPanel gridPanel = new JPanel(gridLayout);
for (int row = 0; row < 3; row++) {
for (int col = 0; col < 3; col++) {
int number = (row + 3) + (col * 3);
String text = String.valueOf(number);
JButton button = new JButton(text);
gridPanel.add(button);
}
}
return gridPanel;
}
private void showGui() {
JFrame frame = new JFrame("Hanoi");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(createGridPanel(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
Hanoi instance = new Hanoi();
EventQueue.invokeLater(instance);
}
}
And here is a screen capture of the running application.
(Note that I am using JDK 12 on Windows 10.)
You can use a grid layout, i change your original code (as you can see below). I recommend to use some designer for the gui, it more easy and clean. Net beans have a nice grafic interface builder.
public class Hanoi {
private JFrame frame;
JButton[][] buttons= new JButton[3][3];
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Hanoi window = new Hanoi();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Hanoi() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 901, 696);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panelone = new JPanel();
panelone.setLayout(new GridLayout(3,3));
frame.getContentPane().add(panelone);
panelone.setBackground(Color.WHITE);
/*GridBagLayout gbl_panelone = new GridBagLayout();
gbl_panelone.columnWidths = new int[]{0};
gbl_panelone.rowHeights = new int[]{0};
gbl_panelone.columnWeights = new double[]{Double.MIN_VALUE};
gbl_panelone.rowWeights = new double[]{Double.MIN_VALUE};*/
// panelone.setLayout(gbl_panelone);
JPanel paneltwo = new JPanel();
frame.getContentPane().add(paneltwo, BorderLayout.NORTH);
paneltwo.setBackground(Color.WHITE);
JLabel lblFunHanoiTower = new JLabel("Fun Hanoi Tower");
lblFunHanoiTower.setForeground(Color.BLACK);
lblFunHanoiTower.setBackground(SystemColor.activeCaption);
lblFunHanoiTower.setFont(new Font("Viner Hand ITC", Font.PLAIN, 36));
paneltwo.add(lblFunHanoiTower);
//JButton[][] buttons = new JButton[3][3];
for(int row = 0; row < buttons.length ; row++) {
for(int col= 0; col < buttons[0].length ;col++) {
buttons[row][col] = new JButton(String.valueOf((row+3)+(col*3)));
buttons[row][col].setFont(new Font("Tempus Sans ITC", Font.BOLD, 16));
buttons[row][col].setBackground(SystemColor.controlHighlight);
buttons[row][col].setSize(66, 66);
panelone.add(buttons[row][col]);
}
}
}
}

Java MouseListener MouseClicked only works once

Im using a JPanel to make a GUI for Game Of Life, my class extends JFrame and implements MouseListener, but when im clicking on a JLabel, the MouseListener works only once.
Any idea what to do?its not a problem in the code in my GameOfLife class because im also trying to print some string and it only works once.
Thanks!
here is the class:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.Border;
public class GameOfLifeWindow extends JFrame implements ActionListener, MouseListener
{
private static final int DEF_ROWS = 16;
private static final int DEF_COLS = 16;
private JLabel[][] cells;
GameOfLife gol;
private JPanel panClear;
private JPanel panCenter;
private JPanel panNextGen;
private JButton nextGen;
private JButton clear;
private JMenuBar menuBar;
private JMenu file;
private JMenuItem newGame;
private JMenuItem loadFile;
public GameOfLifeWindow()
{
super("Game Of Life");
gol = new GameOfLife(DEF_ROWS, DEF_COLS);
//sets layout and dimension
this.getContentPane().setLayout(new BorderLayout());
this.getContentPane().setPreferredSize(new Dimension(300,400));
//Sets the panels
panClear = new JPanel(new FlowLayout());
panCenter = new JPanel(new GridLayout(gol.getRows(), gol.getCols()));
panNextGen = new JPanel(new FlowLayout());
//Adds the panel to the JFrame
this.getContentPane().add(panClear, BorderLayout.NORTH);
this.getContentPane().add(panCenter, BorderLayout.CENTER);
this.getContentPane().add(panNextGen, BorderLayout.SOUTH);
//Sets the next generation button
this.nextGen = new JButton("Next Generation");
panNextGen.add(this.nextGen);
this.nextGen.addActionListener(this);
//Sets the clear button
ImageIcon btnIcon = new ImageIcon(getClass().getResource("images/clear.png"));
Image tmpImg = btnIcon.getImage();
BufferedImage bi = new BufferedImage(30, 30, BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.createGraphics();
g.drawImage(tmpImg, 0, 0, 30, 30, null);
this.clear = new JButton(new ImageIcon(bi));
this.clear.addActionListener(this);
panClear.add(clear);
//Set the GridLayout
this.updateGeneration();
//Set the mouse listener to each cell
for(int i = 0 ; i < this.cells.length ; i++)
for(int j = 0 ; j < this.cells[i].length ; j++)
this.cells[i][j].addMouseListener(this);
//Sets MenuBar
this.menuBar = new JMenuBar();
this.setJMenuBar(menuBar);
//Sets the File menu
this.file = new JMenu("File");
menuBar.add(file);
//Sets the New Game in the file
this.newGame = new JMenuItem("New Game");
this.newGame.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1, InputEvent.CTRL_MASK));
this.newGame.addActionListener(this);
file.add(this.newGame);
//Sets the Load File in the file
this.loadFile = new JMenuItem("Load File");
this.loadFile.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F2, InputEvent.CTRL_MASK));
this.loadFile.addActionListener(this);
file.add(this.loadFile);
}
public void updateGeneration()
//updates the JLabels according to the Game Of Life Screen
{
Border border = BorderFactory.createLineBorder(Color.LIGHT_GRAY);
this.getContentPane().remove(this.panCenter);
this.panCenter = new JPanel(new GridLayout(gol.getRows(), gol.getCols()));
this.cells = new JLabel[gol.getRows()][gol.getCols()];
this.panCenter.removeAll();
for(int i = 0 ; i < cells.length ; i++)
for(int j = 0 ; j < cells[i].length ; j++)
{
this.cells[i][j] = new JLabel();
this.cells[i][j] .setOpaque(true); // make the color visible
this.cells[i][j].setBorder(border);// sets borders
if(gol.isAlive(i, j))
this.cells[i][j].setBackground(Color.BLACK);
else
this.cells[i][j].setBackground(Color.white);
panCenter.add(this.cells[i][j]);
}
this.getContentPane().add(this.panCenter);
this.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e)
{
if(e.getSource() == this.nextGen)
{
this.gol.nexGeneration();
this.updateGeneration();
}
else if(e.getSource() == this.clear)
{
this.gol = new GameOfLife(DEF_ROWS, DEF_COLS);
this.updateGeneration();
}
else if(e.getSource() == this.newGame)
{
this.gol = new GameOfLife(DEF_ROWS, DEF_COLS);
this.updateGeneration();
}
else if(e.getSource() == this.loadFile)
{
String fileName = JOptionPane.showInputDialog("Please Enter A File Name");
this.gol = new GameOfLife(fileName);
System.out.println(gol.toString());
this.updateGeneration();
}
}
#Override
public void mouseClicked(MouseEvent e)
{
boolean found = false;
for(int i = 0 ; i < cells.length && !found ; i++)
for(int j = 0 ; j < cells[i].length && !found; j++)
if(e.getSource() == this.cells[i][j])
{
this.gol.setForGUI(i, j);
found = true;
}
this.updateGeneration();
System.out.println("asdsad");
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
}
In your Constructor you assign a mouse listener to all of your cells which you have in a multidimensional array of JLabel. However, then in your updateGeneration() you create another JLabel[][] array but don't assign your mouse listener to cells again.
To fix you need to add a mouse listener to all the cells again in updateGeneration(). Or instead of creating a new JLabel[][] just update the state of the JLabel in the existing array.

JButtons won't update on button click

Currently displays a GUI with an 8x8 grid of randomized colored buttons. The newButton is to reset the score display to 0 and reset the grid with a fresh like it does on startup after being clicked. I haven't been able to find many solutions other than that it's to do with the way Java displays it's buttons and the way layering works. Here are the 2 classes I'm using.
import javax.swing.JFrame;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.JPanel;
import java.awt.Color;
public class ShinyButtonsApp extends JFrame implements ActionListener {
private static byte ROWS = 8;
public int useThis;
ShinyButtons shiny = new ShinyButtons();
public static ImageIcon[] icons = {new ImageIcon("RedButton.png"),
new ImageIcon("OrangeButton.png"),
new ImageIcon("YellowButton.png"),
new ImageIcon("GreenButton.png"),
new ImageIcon("BlueButton.png"),
new ImageIcon("LightGrayButton.png"),
new ImageIcon("DarkGrayButton.png")};
public ShinyButtonsApp(String title) {
super(title); // Set title of window
setDefaultCloseOperation(EXIT_ON_CLOSE); // allow window to close
setSize(578, 634); // Set size of window
setResizable(false);
getContentPane().setLayout(null);
JLabel aLabel = new JLabel("Score: ");
aLabel.setLocation(10, 570);
aLabel.setSize(80,30);
getContentPane().add(aLabel);
JTextField scoreField = new JTextField();
scoreField.setText(Integer.toString(shiny.score));
scoreField.setEditable(false);
scoreField.setHorizontalAlignment(JTextField.RIGHT);
scoreField.setLocation(60, 570);
scoreField.setSize(120,30);
scoreField.setBackground(Color.WHITE);
getContentPane().add(scoreField);
JButton newButton = new JButton("New Game");
newButton.addActionListener(this);
newButton.setLocation(348,570);
newButton.setSize(110,30);
getContentPane().add(newButton);
JButton quitButton = new JButton("Quit");
quitButton.setLocation(468,570);
quitButton.setSize(80,30);
getContentPane().add(quitButton);
resetButtons2();
}
public void actionPerformed(ActionEvent e) {
shiny.score = 0;
shiny.resetButtons();
resetButtons2();
}
public void resetButtons2() {
for (int r=0; r<ROWS; r++) {
for (int c=0; c<ROWS; c++) {
ImageIcon image1 = icons[(int)shiny.getButton(r,c)];
JButton button = new JButton(image1);
button.setLocation(10+(69*r),10+(69*c));
button.setSize(69,69);
button.setBorder(BorderFactory.createLineBorder(Color.GRAY,1));
getContentPane().add(button);
}
}
}
public static void main(String[] args) {
ShinyButtonsApp frame;
frame = new ShinyButtonsApp("Shiny Buttons"); // Create window
frame.setVisible(true); // Show window
}
}
and
import javax.swing.JFrame;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.JPanel;
import java.awt.Color;
public class ShinyButtons extends JPanel{
public static byte RED = 0;
public static byte ORANGE = 1;
public static byte YELLOW = 2;
public static byte GREEN = 3;
public static byte BLUE = 4;
public static byte LIGHT_GRAY = 5;
public static byte DARK_GRAY = 6;
public static byte ROWS = 8;
public byte[][] buttonTable;
public int score = 0;
public ShinyButtons() {
buttonTable = new byte[ROWS][ROWS];
resetButtons();
}
public void resetButtons() {
for (int r=0; r<ROWS; r++)
for (int c=0; c<ROWS; c++)
buttonTable[r][c] = (byte)(Math.random()*7);
}
public byte getButton(int r, int c) { return buttonTable[r][c]; }
public int getScore() { return score; }
}
Building on to what this answer points out (using layout managers instead of setting size, as you should be doing) you could reset the the images just by looping through the components (JLabels) of the JPanel and changing their icons.
This particular example uses JLabels with MouseListeners but it could easily be switched to JButtons with ActionListeners
newGame.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
reset(iconPanel, icons); <--- call reset method from below
score = 0;
scoreField.setText(String.valueOf(score));
}
});
....
private void reset(JPanel panel, ImageIcon[] icons) {
Component[] comps = panel.getComponents();
Random random = new Random();
for(Component c : comps) {
if (c instanceof JLabel) {
JLabel button = (JLabel)c;
int index = random.nextInt(icons.length);
button.setIcon(icons[index]);
}
}
}
Here's the complete running code. You just need to replace the image paths.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;
public class CircleImages {
private int score = 0;
private JTextField scoreField = new JTextField(10);
public CircleImages() {
scoreField.setEditable(false);
final ImageIcon[] icons = createImageIcons();
final JPanel iconPanel = createPanel(icons, 8);
JPanel bottomLeftPanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
bottomLeftPanel.add(new JLabel("Score: "));
bottomLeftPanel.add(scoreField);
JPanel bottomRightPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
JButton newGame = new JButton("New Game");
bottomRightPanel.add(newGame);
JButton quit = new JButton("Quit");
bottomRightPanel.add(quit);
JPanel bottomPanel = new JPanel(new GridLayout(1, 2));
bottomPanel.add(bottomLeftPanel);
bottomPanel.add(bottomRightPanel);
newGame.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
reset(iconPanel, icons);
score = 0;
scoreField.setText(String.valueOf(score));
}
});
JFrame frame = new JFrame();
frame.add(iconPanel);
frame.add(bottomPanel, BorderLayout.PAGE_END);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void reset(JPanel panel, ImageIcon[] icons) {
Component[] comps = panel.getComponents();
Random random = new Random();
for(Component c : comps) {
if (c instanceof JLabel) {
JLabel button = (JLabel)c;
int index = random.nextInt(icons.length);
button.setIcon(icons[index]);
}
}
}
private JPanel createPanel(ImageIcon[] icons, int gridSize) {
Random random = new Random();
JPanel panel = new JPanel(new GridLayout(gridSize, gridSize));
for (int i = 0; i < gridSize * gridSize; i++) {
int index = random.nextInt(icons.length);
JLabel label = new JLabel(icons[index]);
label.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e) {
score += 1;
scoreField.setText(String.valueOf(score));
}
});
label.setBorder(new LineBorder(Color.GRAY, 2));
panel.add(label);
}
return panel;
}
private ImageIcon[] createImageIcons() {
String[] files = {"blackcircle.png",
"bluecircle.png",
"greencircle.png",
"greycircle.png",
"orangecircle.png",
"redcircle.png",
"yellowcircle.png"
};
ImageIcon[] icons = new ImageIcon[files.length];
for (int i = 0; i < files.length; i++) {
icons[i] = new ImageIcon(getClass().getResource("/circles/" + files[i]));
}
return icons;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new CircleImages();
}
});
}
}
You are creating a new set of buttons in resetButtons2() and placing them on top (or rather under) of the already existing set of buttons in the same locations. You should create the set of buttons once and only update their icons upon reset.
You should do a number of things:
Use a proper layout manager, e.g., GridLayout
Create the 8x8 grid of buttons only once and replace their icons when needed
Call invalidate/repaint to refresh the content pane
And for a JFrame you don't need getContentPane().add(...), you can directly do add(...)
Two things.
First, make sure you remove the existing buttons first. Alternatively, you could simply update the state of the buttons. This would require you to create an array or List of buttons first, which your reset method would then iterate over and update their properties as required.
Second, make use of an appropriate layout manager. A null layout ias a very bad idea. You do not control the font metrics of the underlying platform and this will change how your buttons look on different systems, making your UI less dynamic then it should be

Update JFrame contents

How can I update the contents of a JFrame at a button click. I am building a image viewer where a list of photopath will be passed in and the user will have to click on the next or previous button to go back and forth and see the images. How can change the images and update the Jframe Below is my current implementation. I tried to dispose of the current frame and make a new one but that is not what I am looking for...
package cs213.photoAlbum.simpleview;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.*;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import model.photoNode;
public class ImageViewer {
private JFrame frame = new JFrame("Image Viewer");
private Container pane = frame.getContentPane();
private JPanel imgViewPanel = new JPanel();
JSlider slider = new JSlider(0, 100, 100);
JLabel percent = new JLabel("100%");
String imageFile = "";
private class ImageView extends JScrollPane {
JPanel panel = new JPanel();
Dimension originalSize = new Dimension();
Image originalImage;
JLabel iconLabel;
public ImageView(ImageIcon icon) {
this.originalImage = icon.getImage();
panel.setLayout(new BorderLayout());
iconLabel = new JLabel(icon);
panel.add(iconLabel);
setViewportView(panel);
originalSize.width = icon.getIconWidth();
originalSize.height = icon.getIconHeight();
}
public void update() {
int min = slider.getMinimum();
int max = slider.getMaximum();
int span = max - min;
int value = slider.getValue();
double multiplier = (double) value / span;
multiplier = multiplier == 0.0 ? 0.01 : multiplier;
Image scaled = originalImage.getScaledInstance((int) (originalSize.width * multiplier), (int) (originalSize.height * multiplier), Image.SCALE_FAST);
iconLabel.setIcon(new ImageIcon(scaled));
}
}
ImageView imageView;
public ImageViewer(String imgFile, final ArrayList<photoNode> list) {
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
});
createAndShowGUI();
imageFile = imgFile;
ImageIcon icon = new ImageIcon(imageFile);
imageView = new ImageView(icon);
JPanel panel = new JPanel();
panel.add(new JLabel("Set Image Size: "));
panel.add(slider);
panel.add(percent);
pane.add(panel, BorderLayout.NORTH);
imgViewPanel.add(imageView);
pane.add(imgViewPanel, BorderLayout.CENTER);
slider.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
if (!slider.getValueIsAdjusting()) {
percent.setText(slider.getValue() + "%");
imageView.update();
}
}
});
JButton next = new JButton("Next");
JButton prev = new JButton("Prev");
pane.add(next, BorderLayout.EAST);
pane.add(prev, BorderLayout.WEST);
next.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
imgViewPanel.remove(imageView);
if (list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
if (list.get(i).fileName.equalsIgnoreCase(imageFile)) {
if (i + 1 < list.size()) {
//frame.dispose();
ImageIcon icon = new ImageIcon(list.get(i + 1).fileName);
ImageView imageView = new ImageView(icon);
imgViewPanel.add(imageView);
pane.add(imgViewPanel, BorderLayout.CENTER);
imgViewPanel.revalidate();
break;
}
}
}
}
}
});
}
private void createAndShowGUI() { // Creating the GUI...
frame.getContentPane().setBackground(Color.WHITE);
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.setTitle("PhotoAlbum55");
frame.pack();
frame.setSize(400, 300);
frame.setLocationRelativeTo(null);
frame.setResizable(true);
frame.setVisible(true);
}
}
The easiest way to swap images is to display them as ImageIcons in a JLabel and simply call setIcon(...) on the JLabel passing in another ImageIcon. If the images are small enough, you could create a collection of icons, perhaps a List<Icon>, and then move backwards or forwards through the list on next or previous button press.

Categories