The JavaSwing application shows no errors in netbeans. When I try to run it, it takes forever and nothing is happening(JDK 8 + Netbeans 8.1). The same problem in eclipse. A simple hello world program works. The program is divided in 4 classes. Sorry for the long code.
package test2;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
public class MainWindow extends JFrame {
private Navigator navigator = new Navigator(this);
private Field spielfeld = new Field();
public MainWindow() {
super("GameTest");
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.add(spielfeld);
this.setResizable(false);
this.pack();
}
public static void main(String[] args) {
new MainWindow();
}
}
package test2;
import javax.swing.JPanel;
import javax.swing.JLabel;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
public class Field extends JPanel {
private static int x = 10;
private static int y = 10;
private JLabel[][] fields = new JLabel[10][10];
public Field() {
Dimension dim = new Dimension();
dim.setSize(50, 50);
this.setLayout(new GridLayout(x, y));
for(int i = 0; i < y; i++){
for(int j = 0; j < x; j++){
fields[i][j] = new JLabel();
fields[i][j].setPreferredSize(dim);
fields[i][j].setOpaque(true);
if((i+j)%2 == 0){
fields[i][j].setBackground(Color.BLACK);
}
else {
fields[i][j].setBackground(Color.WHITE);
}
this.add(fields[i][j]);
}
}
}
}
package test2;
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JWindow;
public class Navigator extends JWindow {
public Navigator(JFrame parent) {
super(parent);
JPanel frame = new JPanel();
frame.setLayout(new BorderLayout());
frame.setBorder(BorderFactory.createLineBorder(Color.RED));
frame.add(new Keypad(), BorderLayout.NORTH);
this.getContentPane().add(frame);
this.updateLocation();
this.pack();
}
public void updateLocation()
{
this.setLocation((int)this.getParent().getLocation().getX() + this.getParent().getWidth() + 550,
(int)this.getParent().getLocation().getY());
}
public MainWindow getMainWindow()
{
return (MainWindow)this.getParent();
}
}
package test2;
import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
public class Keypad extends JPanel {
public Keypad() {
Dimension dim = new Dimension(60, 30);
this.setLayout(new GridLayout(3, 3));
this.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
for(int i = 9; 0 < i; i--) {
JButton button = new JButton(String.valueOf(i));
button.setPreferredSize(dim);
button.setVisible(true);
if(i != 5) {
this.add(button);
this.add(button);
}
}
this.setVisible(true);
}
}
You are missing setVisible(true) inside your MainWindow constructor.
The code will "run forever" with or without this line. The only difference is that the window will be shown.
Related
I want to add 100 buttons into an GridLayout and my code works but sometimes it only adds one button and if I click where the other buttons belong the button where I clicked appears.
it happens totally randomly and I don't get it.
Here is my code:
public class GamePanel extends JPanel {
GameUI controler;
GridLayout gameLayout = new GridLayout(10,10);
JButton gameButtons[] = new JButton[100];
ImageIcon ice;
JButton startButton;
JButton exitButton;
ImageIcon startIcon;
ImageIcon exitIcon;
URL urlIcon;
private int i;
public GamePanel(GameUI controler) {
this.setLayout(gameLayout);
this.controler = controler;
urlIcon = this.getClass().getResource("/icons/Overlay.png");
ice = new ImageIcon(urlIcon);
makeButtons();
}
#Override
public void paint(Graphics g) {
super.paint(g);
}
public void makeButtons() {
for(i = 0; i< 100; i++) {
gameButtons[i] = new JButton(ice);
this.add(gameButtons[i]);
revalidate();
}
repaint();
}
}
update:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.net.URL;
public class GameUI extends JFrame {
ImageIcon i;
Image jFrameBackground;
JButton startButton;
JButton exitButton;
ImageIcon startIcon;
ImageIcon exitIcon;
public GameUI() {
setResizable(false);
this.setSize(1200, 800);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(null);
BackGroundPanel backGroundPanel = new BackGroundPanel();
GamePanel panel = new GamePanel(this);
ButtonPanel buttonPanel = new ButtonPanel();
panel.setSize(500,500);
panel.setLocation(100, 150);
backGroundPanel.setSize(this.getWidth(),this.getHeight());
backGroundPanel.setLocation(0,0);
buttonPanel.setSize(390,50);
buttonPanel.setLocation(100,100);
this.add(backGroundPanel);
this.add(panel);
this.add(buttonPanel);
backGroundPanel.setBackground(Color.BLACK);
}
public static void main(String[] args) throws InvocationTargetException, InterruptedException {
javax.swing.SwingUtilities.invokeAndWait(
new Runnable(){
#Override
public void run() {
GameUI ui = new GameUI();
ui.setVisible(true);
}
}
);
}
}
As I mentioned in comments, you're using a null layout, and this is the source of your problems.
You're using the null layout to try to layer JPanels, one on top of the other, and that is not how it should be used or what it is for, nor how you should create backgrounds. This is having the effect of the background covering your buttons until your mouse hovers over them.
Instead if you wish to create a background image, I would recommend that you:
create a JPanel, say called BackgroundPanel,
override its paintComponent method,
call its super.paintComponent(g); on your method's first line
then draw the image it should display
then give it a decent layout manager
and add your GUI components to it
Make sure that any JPanels added to it are made transparent via .setOpaque(false)
Other options include using a JLayeredPane, but you really don't need this just to have a background.
For example, the following code produces:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
public class GameUI2 {
private static final String IMG_PATH = "https://upload.wikimedia.org/wikipedia/commons/3/3f/"
+ "Butterfly_Nebula_in_narrow_band_Sulfur%2C_Hydrogen_and_Oxygen_Stephan_Hamel.jpg";
private static final String BTN_IMG_PATH = "https://upload.wikimedia.org/wikipedia/commons/5/54/Crystal_Project_Games_kids.png";
private static void createAndShowGui() {
BufferedImage bgImg = null;
BufferedImage btnImg = null;
try {
URL bgImgUrl = new URL(IMG_PATH);
URL btnImgUrl = new URL(BTN_IMG_PATH);
bgImg = ImageIO.read(bgImgUrl);
btnImg = ImageIO.read(btnImgUrl);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
BackgroundPanel2 mainPanel = new BackgroundPanel2(bgImg);
mainPanel.setLayout(new GridBagLayout());
GamePanel2 gamePanel = new GamePanel2(btnImg);
mainPanel.add(gamePanel);
JFrame frame = new JFrame("Game");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.setResizable(false);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
#SuppressWarnings("serial")
class BackgroundPanel2 extends JPanel {
private Image backgroundImg;
public BackgroundPanel2(Image backgroundImg) {
this.backgroundImg = backgroundImg;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (backgroundImg != null) {
g.drawImage(backgroundImg, 0, 0, this);
}
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet() || backgroundImg == null) {
return super.getPreferredSize();
} else {
int w = backgroundImg.getWidth(this);
int h = backgroundImg.getHeight(this);
return new Dimension(w, h);
}
}
}
#SuppressWarnings("serial")
class GamePanel2 extends JPanel {
public static final int MAX_BUTTONS = 100;
private static final int IMG_WIDTH = 40;
JButton[] gameButtons = new JButton[MAX_BUTTONS];
public GamePanel2(Image buttonImg) {
setOpaque(false);
if (buttonImg.getWidth(this) > IMG_WIDTH) {
buttonImg = buttonImg.getScaledInstance(IMG_WIDTH, IMG_WIDTH, Image.SCALE_SMOOTH);
}
Icon icon = new ImageIcon(buttonImg);
setLayout(new GridLayout(10, 10, 4, 4));
for (int i = 0; i < gameButtons.length; i++) {
int finalIndex = i;
JButton btn = new JButton(icon);
btn.addActionListener(e -> {
String text = String.format("Button: %02d", finalIndex);
System.out.println(text);
});
add(btn);
gameButtons[i] = btn;
}
}
}
I need to display a user-inputted number of tabs (JTabbedPane) (with the same initial content, but the ability to individually change the content), is there a way to create these components procedurally so I don't have to know how many there will be before the user input?
Here is an example of change number of tabse depended on user input:
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class TabbedPaneTest3 implements Runnable {
private final JTabbedPane tabber = new JTabbedPane();
public static void main(String[] args) {
SwingUtilities.invokeLater(new TabbedPaneTest3());
}
#Override
public void run() {
final JSpinner spinner = new JSpinner(new SpinnerNumberModel(3, 1, 10, 1));
spinner.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
Object val = spinner.getValue();
if (val instanceof Number) {
updateTabsNumber((Number) val);
}
}
});
updateTabsNumber(3);
JFrame frm = new JFrame("Tab Pane");
JPanel panel = new JPanel();
panel.add(new JLabel("Number of tabs: "));
panel.add(spinner);
frm.add(panel, BorderLayout.NORTH);
frm.add(tabber);
frm.setSize(600, 400);
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.setLocationRelativeTo(null);
frm.setVisible(true);
}
private void updateTabsNumber(Number val) {
int count = val.intValue();
tabber.removeAll();
for (int i = 0; i < count; i++) {
String text = "Tab " + (i + 1);
JTextArea area = new JTextArea(10, 30);
area.setText("Initial text for tab: " + (i + 1));
tabber.addTab(text, new JScrollPane(area));
}
}
}
I have a problem that I can't display all the labels in the window
I created 20 labels in the arraylist, but sometimes I get 10, another I got 14 later it became 19 (from 0 to 19). So it cant't display all the labels from the first time.
package Windows;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class Protofenetre extends JFrame {
public JPanel panneau;
public ArrayList<JLabel> labels = new ArrayList<JLabel>();
public Protofenetre ()
{
this.setTitle ("The Scopy Zoo :D");
this.setSize(500, 500);
this.setLocationRelativeTo(null);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panneau = new JPanel();
panneau.setLayout(null);
this.setContentPane(panneau);
}
}
Here is my Main CLass
package Concession;
import javax.swing.JLabel;
import Windows.Protofenetre;
public class Main_Class {
public static void main(String[] args) {
Protofenetre fenetre = new Protofenetre ();
for(int i=0; i<20; i++)
{
JLabel temp = new JLabel();
temp.setBounds(20, i*20, 200, 100);
temp.setText("pixels" + String.valueOf(i));
temp.setVisible(true);
fenetre.panneau.add(temp);
fenetre.labels.add(temp);
}
}
}
Thanks in advance
Actually I want to add image and text both in combo box . I have use JLabel for that but it doesn't work so how can I achieve this.
Here is my code :
package swing;
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.util.Vector;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class ComboBox {
public ComboBox() {
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("ComboBOx");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container con = frame.getContentPane();
JLabel ar[] = new JLabel[5];
ar[0] = new JLabel("ganesh",new ImageIcon("/images/g.jpg"),JLabel.HORIZONTAL);
ar[1] = new JLabel("ganes",new ImageIcon("/images/g.jpg"),JLabel.HORIZONTAL);
ar[2] = new JLabel("gane",new ImageIcon("/images/g.jpg"),JLabel.HORIZONTAL);
ar[3] = new JLabel("gan",new ImageIcon("/images/g.jpg"),JLabel.HORIZONTAL);
ar[4] = new JLabel("ga",new ImageIcon("/images/g.jpg"),JLabel.HORIZONTAL);
JComboBox<JLabel> box = new JComboBox<JLabel>(ar);
con.add(box);
con.setBackground(Color.white);
con.setLayout(new FlowLayout());
frame.setVisible(true);
frame.pack();
}
public static void main(String args[]) {
new ComboBox();
}
}
#MadProgrammer Thanks, I find my answer
package swing;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.FlowLayout;
import java.util.Vector;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
public class ComboBox {
ImageIcon imageIcon[] = { new ImageIcon("/images/g.jpg"), new ImageIcon("/images/g.jpg"),
new ImageIcon("/images/g.jpg"), new ImageIcon("/images/g.jpg"), new ImageIcon("/images/g.jpg") };
Integer array[] = {1,2,3,4,5};
String names[] = {"img1","img2","img3","img4","img5"};
public ComboBox() {
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("ComboBOx");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container con = frame.getContentPane();
ComboBoxRenderar rendrar = new ComboBoxRenderar();
JComboBox box = new JComboBox(array);
box.setRenderer(rendrar);
con.add(box);
con.setLayout(new FlowLayout());
frame.setVisible(true);
frame.pack();
}
public class ComboBoxRenderar extends JLabel implements ListCellRenderer {
#Override
public Component getListCellRendererComponent(JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
int offset = ((Integer)value).intValue() - 1 ;
ImageIcon icon = imageIcon[offset];
String name = names[offset];
setIcon(icon);
setText(name);
return this;
}
}
public static void main(String args[]) {
new ComboBox();
}
}
I'm having trouble getting my GUI to contain any of my JButtons or JTextField. I have two classes One "SnowballFight" class that contains my main method and frame constructor. Then I also have "GameBoard" which sets up my GUI. My problem is that my GUI appears, but appears empty.
"SnowballFight" class:
package snowballfight;
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JTextField;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class SnowballFight extends JFrame implements ActionListener{
public SnowballFight(){
setLayout(new BorderLayout(1,2));
}
public static void main(String[] args) {
SnowballFight frame = new SnowballFight();
GameBoard game = new GameBoard(frame);
}
public void actionPerformed(ActionEvent event) {
}
}
"GameBoard" class:
package snowballfight;
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JTextField;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class GameBoard extends JFrame implements ActionListener{
private JButton[][] game = new JButton[10][10];
private JTextField display = new JTextField("Welcome to the SnowBall fight!");
private Opponent[] opponents = new Opponent[4];
public GameBoard(SnowballFight frame){
JPanel panel = new JPanel();
panel.setLayout(new GridLayout( 10, 10));
for (int row = 0; row < game.length; row++) {
for (int col = 0; col < game[row].length; col++) {
game[row][col] = new JButton();
game[row][col].setBackground(Color.gray);
game[row][col].addActionListener(this);
panel.add(game[row][col]);
}
}
add(display, BorderLayout.NORTH);
add(panel, BorderLayout.SOUTH);
frame.setTitle("Snowball Fight");
frame.setSize(200, 150);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public boolean isGameOver(){
for (int opponent = 0; opponent < opponents.length; opponent++) {
if(opponents[opponent].isSoaked() == false ){
return false;
}
}
return true;
}
public void actionPerformed(ActionEvent event) {
}
}
Not sure why there are two frames, but I think you're adding display and panel to the wrong frame.
Try changing:
add(display, BorderLayout.NORTH);
add(panel, BorderLayout.SOUTH);
to:
frame.add(display, BorderLayout.NORTH);
frame.add(panel, BorderLayout.SOUTH);
You never make the GameBoard JFrame visible
game.setVisible(true);
Some notes:
The frame SnowballFight has no apparent function
It's not necessary to extend JFrame since no functionality is being added
Read The Use of Multiple JFrames, Good/Bad Practice?