I have a scrollpane where load an image. I wont this image with her natural size, and if this image is too big, I wont activated the scrollbar, but this instruction
g.drawImage(immagine, 0, 0, getWidth(), getHeight(), this);
scaled image for placing in scrollpane. What can I do?
Class Gui:
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import javax.swing.*;
public class Gui implements ActionListener {
private JFrame frmEditor;
private Mappa content;
private JMenuItem mntmSfondo;
private JScrollPane scrollabile;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Gui window = new Gui();
window.frmEditor.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Gui() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frmEditor = new JFrame();
frmEditor.setFont(UIManager.getFont("TextArea.font"));
frmEditor.setBounds(50, 50, 1024, 768);
frmEditor.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmEditor.getContentPane().setLayout(new BorderLayout(0, 0));
JPanel panelTile = new JPanel();
panelTile.setLayout(new BorderLayout(0, 0));
content = new Mappa(null);
content.setMinimumSize(new Dimension(150, 150));
scrollabile = new JScrollPane(content);
frmEditor.getContentPane().add(scrollabile, BorderLayout.CENTER);
inizializzaMenu();
}
/**
* Initialize the menu.
*/
private void inizializzaMenu() {
JMenuBar menuBar = new JMenuBar();
frmEditor.setJMenuBar(menuBar);
JMenu mnAltro = new JMenu("Modify");
menuBar.add(mnAltro);
mntmSfondo = new JMenuItem("Load Background");
mntmSfondo.addActionListener(this);
mnAltro.add(mntmSfondo);
}
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source == mntmSfondo) {
JFileChooser fc = new JFileChooser("tuttiSfondi");
int result = fc.showOpenDialog(null);
if (result == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
try {
content.setImage(file);
//content = new Mappa(file);
//scrollabile.setViewportView(content);
} catch (Exception ex) {
}
}
if (result == JFileChooser.CANCEL_OPTION) {
}
}
}
}
Class Mappa:
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;
public class Mappa extends JPanel {
BufferedImage immagine;
public Mappa(File fileImmagine) {
if (fileImmagine != null ) {
BufferedImage img = null;
try {
img = ImageIO.read(new File(fileImmagine.getPath()));
} catch (IOException e) {
e.printStackTrace();
}
this.immagine = img;
}
repaint();
}
public void setImage(File file) throws IOException {
this.immagine = ImageIO.read(file);
String name = file.getPath();
System.out.println(name);
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.clearRect(0, 0, 4000, 4000);
g.drawImage(this.immagine, 0, 0, getWidth(), getHeight(), this);
System.out.println("Called Repaint() on Mappa");
}
}
JScrollPane, or more to the point JViewport will use the component's (or in this case the "view's") preferred size as a bases for determining how big the view should be.
When the view expands beyond the size of the scroll pane, it will show the scroll bars.
So basically, you need to override the getPreferredSize of the public class Mappa extends JPanel { panel, for example
public class Mappa extends JPanel {
//...
public Dimension getPreferredSize() {
return immagine == null ? new Dimension(200, 200) : new Dimension(immagine.getWidth(), immagine.getHeight());
}
//...
}
This will encourage the JViewport to always be the same size as the image.
Also, two things...
First, you shouldn't rely on magic numbers, for example
g.clearRect(0, 0, 4000, 4000);
Should be more like...
g.clearRect(0, 0, getWidth(), getHeight());
And secondly,
super.paintComponent(g);
Will do this any way, so calling clearRect is kind of pointless...
You might also like to take a look at Scrollable, but it is quite an advanced topic
I wont this image with her natural size, and if this image is too
big, I wont activated the scrollbar,
Using JLabel to contain the image and wrap it in a JScrollPane should easily achieve what you want. Take hints from the following example:
class AFrame extends JFrame
{
public AFrame()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Image view Demo with JScrollPane");
ImageIcon image = new ImageIcon("myImage.png"); // pass the file location of an image
JLabel label = new JLabel(image);
JScrollPane scrollPane = new JScrollPane(label);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
add(scrollPane, BorderLayout.CENTER);
pack();
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new AFrame().setVisible(true);
}
});
}
}
Related
I am trying to implement a GUI for a maze-based game I created that meets the following specific conditions:
The GUI itself has a set size and is not resizable (line 41) .
The master panel (line 57) that contains all the maze images is scrollable. All maze image components are flush with each other.
If maze is small enough, then entire maze will be visible in master panel.
If maze is very large, then user would need to scroll.
The master panel needs to be accessed by a mouse listener (line 130) that returns the component that is being clicked.
The following code seems to meet criteria 1 and 3, but fails criteria 2:
public class MazeGui extends JFrame implements DungeonView {
private final Board board;
public MazeGui(ReadOnlyModel m) {
//this.setSize(m.getNumRows()*100, m.getNumCols()*100);
this.setSize(600, 600);
this.setLocation(200, 200);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
this.board = new Board(m);
JScrollPane scroller = new JScrollPane(board);
this.add(scroller, BorderLayout.CENTER);
setTitle("Dungeon Escape");
}
private class Board extends JPanel {
private ReadOnlyModel m;
public Board(ReadOnlyModel m) {
this.m = m;
GridLayout layout = new GridLayout(m.getNumRows(),m.getNumCols(), 0, 0);
// layout.setHgap(-100);
// layout.setVgap(-100);
this.setLayout(layout);
this.setSize(m.getNumRows()*64,m.getNumCols()*64);
for (int i = 0; i < m.getNumRows() * m.getNumCols(); i++) {
try {
// load resource from the classpath instead of a specific file location
InputStream imageStream = getClass().getResourceAsStream(String.format("/images/%s.png", m.getRoomDirections(i + 1)));
// convert the input stream into an image
Image image = ImageIO.read(imageStream);
// add the image to a label
JLabel label = new JLabel(new ImageIcon(image));
label.setPreferredSize(new Dimension(64, 64));
JPanel panel = new JPanel();
panel.setSize(64, 64);
String name = String.format("%d", i);
panel.setName(name);
panel.add(label);
// add the label to the JFrame
//this.layout.addLayoutComponent(TOOL_TIP_TEXT_KEY, label);
this.add(panel);
} catch (IOException e) {
JOptionPane.showMessageDialog(this, e.getMessage());
e.printStackTrace();
}
}
}
}
#Override
public void addClickListener(DungeonController listener) {
Board board = this.board;
MouseListener mouseListener = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
System.out.println(String.format("(%d,%d)", e.getX(), e.getY()));
JPanel panel = (JPanel) board.getComponentAt(e.getPoint());
System.out.println(panel.getName());
}
};
board.addMouseListener(mouseListener);
}
#Override
public void refresh() {
this.repaint();
}
#Override
public void makeVisible() {
this.setVisible(true);
}
}
Here is an image of what it produces:
First, I'd make use of a different layout manager, one which would try and expand to fit the size of the underlying container.
Then, I would let the components do their jobs. I don't know why you're adding the label to another panel, the panel doesn't seem to be adding additional functionality/features and is just adding to the complexity.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
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 Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
List<Maze.Direction> directions = new ArrayList<>(32);
directions.add(Maze.Direction.EAST_SOUTH);
directions.add(Maze.Direction.EAST_SOUTH_WEST);
directions.add(Maze.Direction.EAST_SOUTH_WEST);
directions.add(Maze.Direction.EAST_SOUTH_WEST);
directions.add(Maze.Direction.EAST_SOUTH_WEST);
directions.add(Maze.Direction.SOUTH_WEST);
directions.add(Maze.Direction.NORTH_EAST_SOUTH);
directions.add(Maze.Direction.NORTH_EAST_SOUTH_WEST);
directions.add(Maze.Direction.NORTH_EAST_SOUTH_WEST);
directions.add(Maze.Direction.NORTH_EAST_SOUTH_WEST);
directions.add(Maze.Direction.NORTH_EAST_SOUTH_WEST);
directions.add(Maze.Direction.NORTH_SOUTH_WEST);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH);
directions.add(Maze.Direction.NORTH);
directions.add(Maze.Direction.NORTH);
directions.add(Maze.Direction.NORTH);
directions.add(Maze.Direction.NORTH);
directions.add(Maze.Direction.NORTH);
System.out.println(directions.size());
Maze maze = new DefaultMaze(5, 6, directions);
MazeGui frame = new MazeGui(maze);
frame.addClickListener(null);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public interface Maze {
enum Direction {
EAST_SOUTH("EastSouth.png"), EAST_SOUTH_WEST("EastSouthWest.png"), SOUTH_WEST("SouthWest.png"),
NORTH_EAST_SOUTH("NorthEastSouth.png"), NORTH_EAST_SOUTH_WEST("NorthEastSouthWest.png"),
NORTH_SOUTH_WEST("NorthSouthWest.png"), NORTH_SOUTH("NorthSouth.png"), NORTH("North.png");
private BufferedImage image;
private Direction(String name) {
try {
image = ImageIO.read(getClass().getResource("/images/" + name));
} catch (IOException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
public BufferedImage getImage() {
return image;
}
}
public int getRows();
public int getColumns();
public Direction getRoomDirections(int index);
}
public class DefaultMaze implements Maze {
int rows;
int columns;
private List<Direction> directions;
public DefaultMaze(int rows, int columns, List<Direction> directions) {
this.rows = rows;
this.columns = columns;
this.directions = directions;
}
public int getRows() {
return rows;
}
public int getColumns() {
return columns;
}
#Override
public Direction getRoomDirections(int index) {
return directions.get(index);
}
}
public class MazeGui extends JFrame {
// Missing code
public interface DungeonController {
}
private final Board board;
public MazeGui(Maze m) {
this.setSize(600, 600);
this.setResizable(false);
this.board = new Board(m);
JScrollPane scroller = new JScrollPane(board);
this.add(scroller, BorderLayout.CENTER);
setTitle("Dungeon Escape");
}
public Board getBoard() {
return board;
}
public void addClickListener(DungeonController listener) {
Board board = getBoard();
board.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
Component cell = board.getComponentAt(e.getPoint());
System.out.println(cell.getName());
board.highlight(cell.getBounds());
}
});
}
private class Board extends JPanel {
private Rectangle selectedCell;
private Maze maze;
public Board(Maze maze) {
this.maze = maze;
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
for (int index = 0; index < maze.getRows() * maze.getColumns(); index++) {
Maze.Direction direction = maze.getRoomDirections(index);
JLabel label = new JLabel(new ImageIcon(direction.getImage()));
label.setName(direction.name());
add(label, gbc);
gbc.gridx++;
if (gbc.gridx >= maze.getColumns()) {
gbc.gridx = 0;
gbc.gridy++;
}
}
// addMouseListener(new MouseAdapter() {
// #Override
// public void mouseClicked(MouseEvent e) {
// Component component = getComponentAt(e.getPoint());
// selectedCell = null;
// if (component != null) {
// selectedCell = component.getBounds();
// }
// repaint();
// }
// });
}
public void highlight(Rectangle bounds) {
selectedCell = bounds;
repaint();
}
#Override
public void paint(Graphics g) {
super.paint(g);
if (selectedCell != null) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(new Color(0, 0, 255, 128));
g2d.fill(selectedCell);
g2d.dispose();
}
}
}
}
}
The GUI itself has a set size and is not resizable
So the issue here is that you are forcing the "board" panel to have an arbitrary size.
this.setSize(600, 600);
The actual size of the panel should be 8 * 64 = 512. So extra space is being added to each grid.
Don't hardcode size values.
It is the job of the layout manager to determine the preferred size of each component.
So instead of using setSize(...) you should pack() the frame before making it visible:
this.pack();
this.setVisible(true);
When you do this you will see that the maze fits completely in the frame.
If you want extra space around the maze then you need to add a "border" to your board:
setBorder( new EmptyBorder(88, 88, 88, 88) );
GridLayout layout = new GridLayout(m.getNumRows(),m.getNumCols(), 0, 0);
Turns out I should have been using GridBagLayout!
There is no need to change layout managers, only use the layout managers more effectively.
If you really for some reason need to specify a fixed frame size then you can make the following change:
//this.add(scroller, BorderLayout.CENTER);
JPanel wrapper = new JPanel( new GridBagLayout() );
wrapper.add(scroller, new GridBagConstraints());
this.add(wrapper, BorderLayout.CENTER);
This will allow the "board" panel to be displayed at its preferred size and the "board" panel will be centered in its parent container.
Using these tips will help you effectively create more complicated layouts.
I want to create a window(JFrame) and draw a string on it.However, when i run my code the window appears but without the string i want to draw on it. I have made two classes LabelFrame and WebStalker.
Here is my code :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.net.*;
public class LabelFrame extends JFrame {
private final JTextField urlString;
private final JButton backButton;
private final JButton loadButton;
private Stack urlStack = new Stack();
String content;
class GraphicPane extends JComponent {
public GraphicPane() {
super();
}
#Override
public void paint(Graphics g) {
g.setFont(new Font(Font.SANS_SERIF, Font.ITALIC, 14));
g.drawString("Hello, World!", 30, 20);
}
}
public LabelFrame() {
setTitle("WebStalker");
setSize(600, 600);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
setLayout(new FlowLayout());
urlString = new JTextField(30);
backButton = new JButton("Load");
loadButton = new JButton("Back");
GraphicPane gp = new GraphicPane();
this.add(new JLabel("URL"));
this.add(urlString);
this.add(loadButton);
this.add(backButton);
this.add(gp);
TextFieldHandler tHandler = new TextFieldHandler();
ButtonHandler bHandler = new ButtonHandler();
urlString.addActionListener(tHandler);
backButton.addActionListener(bHandler);
loadButton.addActionListener(bHandler);
}
private class TextFieldHandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent event){
content = URLReaderFinal.Reading(event.getActionCommand());
}
}
private class ButtonHandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent event) {
if (event.getSource() == loadButton) {
try {
//remember url for back button
urlStack.push(urlString.getText());
content = URLReaderFinal.Reading(urlString.getText());
} catch (Exception e) {
System.out.println("Unable to load page");
}
} else if (event.getSource() == backButton) {
if (urlStack.size() <= 1) {
return;
}
try {
urlStack.pop();
String urlString = (String)urlStack.peek();
} catch (Exception e) {
System.out.println("Unable to load page");
}
}
}
}
}
And the other class :
import java.awt.*;
import javax.swing.*;
public class WebStalker extends JFrame {
public static void main(String[] args) {
LabelFrame frame = new LabelFrame();
frame.setVisible(true);
}
}
You panel is using a FlowLayout. A FlowLayout respects the preferred size of a component. The preferred size of your custom component is (0, 0) so there is nothing to paint.
Override the getPreferredSize() method to return a proper size for your component.
Also, custom painting is done by overriding the paintComponent() method.
Since you are extending JComponent you should also do a fillRect(...) on the entire size of the component to make sure the background is cleared. It would be easier to extend JPanel, then you can just invoke super.paintComponent() at the start to clear the background.
Read the section from the Swing tutorial on Custom Painting for working example and more information on both of these suggestions.
I wrote JPanel class where I load image. I'm trying to add a scrolls to this panel, but it didn't work. Can someone help me? Sorry for my bad language.
browser.setFileFilter(imgFilter); // ustawienie filtra
browser.setAcceptAllFileFilterUsed(false);
browser.setCurrentDirectory(new File("."));
int result = browser.showOpenDialog(imagePanel);
if (result == JFileChooser.APPROVE_OPTION) {
// tworzenie obrazu
imagePanel = new ImagePanel(browser.getSelectedFile());
JScrollPane scrollPane = new JScrollPane(imagePanel);
scrollPane.setSize(new Dimension(300, 400));
//add(imagePanel);
add(scrollPane);
//imagePanel.repaint();
scrollPane.repaint();
}
And this is my imagePanel class:
private class ImagePanel extends JPanel {
private Image img;
private File file;
public ImagePanel(File file) {
this.file = file;
setSize(SCREEN_HEIGHT / 2, SCREEN_WIDTH * 3/4);
try {
img = ImageIO.read(file);
}
catch(IOException e) {
System.out.println("Wystąpił błąd podczas wczytywanie obrazu.");
e.printStackTrace();
}
}
public void paintComponent(Graphics g) {
if(img == null) return;
g.drawImage(img, 0, 0, null);
}
}
You should be overriding the getPreferredSize() of the ImagePanel to give the panel a preferred size, which the scroll pane will use to determine whether or not to add scrolls. Generally, when doing custom painting, you always want to override the getPreferredSize of the drawing canvas panel, as the default is 0x0
Example:
public class Test {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
// image is 256 x 256
Image image = new ImageIcon("stackoverflow.png").getImage();
JPanel imagePanel = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(image.getWidth(this),
image.getHeight(this));
}
};
JScrollPane pane = new JScrollPane(imagePanel);
pane.setPreferredSize(new Dimension(200, 200));
JOptionPane.showMessageDialog(null, pane);
}
});
}
}
With getPreferredSize
Without getPreferredSize
UPDATE
A couple thing I see wrong with your current code.
Creating a new ImagePanel when you want to set the image. Instead just have a method like setImage in the ImagePanel class where you can just set the image and repaint.
Trying to add(scrollPane); at runtime without revalidate().
See full example here.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileNameExtensionFilter;
public class Test {
public Test() {
JFrame frame = new JFrame();
ImagePanel panel = new ImagePanel();
JScrollPane pane = new JScrollPane(panel);
pane.setPreferredSize(new Dimension(200, 200));
JButton button = createButton(panel, pane);
frame.add(pane);
frame.add(button, BorderLayout.PAGE_END);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private JButton createButton(ImagePanel panel, JScrollPane pane) {
JButton button = new JButton("Change image");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JFileChooser chooser = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter(
"JPG & GIF Images", "jpg", "gif");
chooser.setFileFilter(filter);
int returnVal = chooser.showOpenDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION) {
Image image = new ImageIcon(
chooser.getSelectedFile().getAbsolutePath()).getImage();
panel.setImage(image);
pane.revalidate();
}
}
});
return button;
}
private class ImagePanel extends JPanel {
Image image;
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image != null) {
g.drawImage(image, 0, 0, this);
}
}
#Override
public Dimension getPreferredSize() {
return image == null ? new Dimension(150, 150)
: new Dimension(image.getWidth(this),
image.getHeight(this));
}
public void setImage(Image img) {
this.image = img;
repaint();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Test();
}
});
}
}
I'm just trying to load in 9 identical .gif's of doges. That's all I wanna do. Please help!
It's for a project of a modified version of tic-tac-toe, and for some reason I can't get the images to appear in my window. Help!
package jerryTacToe;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
class picture extends JPanel
{
/**
*
*/
private static final long serialVersionUID = 1L;
ImageIcon doge;
public picture() throws IOException
{
doge = new ImageIcon("dogeRotates.gif", null);
JPanel panel = new JPanel();
JLabel label = new JLabel("", doge, JLabel.CENTER);
panel.add(label, BorderLayout.CENTER);
}
public void paintComponent(Graphics g)
{
((Icon) g).paintIcon(this, g, 10, 10);
/* Graphics2D g2 = (Graphics2D) g;
Line2D line = new Line2D.Float(100, 100, 250, 260);
g2.draw(line);*/
}
public void changeDoge(boolean human) throws IOException
{
if(human)
doge = new ImageIcon("./dogeIntensifies.gif", null);
else
doge = new ImageIcon("./ferociousDoge.gif", null);
}
}
class Closer extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
System.out.println("much derp");
System.exit(0);
}
}
public class Gui extends JFrame
implements ActionListener, MouseListener
{
/**
*
*/
private static final long serialVersionUID = 1L;
boolean human;
JButton goSecond;
picture centerCenter; picture topLeft; picture topCenter;
picture topRight; picture centerLeft; picture centerRight;
picture bottomLeft; picture bottomCenter; picture bottomRight;
public void mouseClicked(MouseEvent e){
if(e.getSource()==topLeft || e.getSource()==topCenter
||e.getSource()==topRight ||
e.getSource()==centerLeft ||e.getSource()==centerCenter
||e.getSource()==centerRight ||
e.getSource()==bottomLeft ||e.getSource()==bottomCenter
||e.getSource()==bottomRight)
{
/*
* Call the AI here.
*
*
* hello?
* yes, this is doge.
* */
}
}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mousePressed(MouseEvent e){}
public void mouseReleased(MouseEvent e){}
public void actionPerformed(ActionEvent e)
{
}
public Gui() throws IOException
{
addWindowListener( new Closer() );
setTitle("DOGE-TAC-TOE (very0.0.4)");
setVisible(true);
setSize(1600,900);
goSecond=new JButton("wow second");
topLeft=new picture();
topCenter=new picture();
topRight=new picture();
centerLeft=new picture();
centerCenter=new picture();
centerRight=new picture();
bottomLeft=new picture();
bottomCenter=new picture();
bottomRight=new picture();
centerCenter.addMouseListener(this);
topLeft.addMouseListener(this);
topCenter.addMouseListener(this);
topRight.addMouseListener(this);
centerLeft.addMouseListener(this);
centerRight.addMouseListener(this);
bottomRight.addMouseListener(this);
bottomCenter.addMouseListener(this);
bottomLeft.addMouseListener(this);
goSecond.addActionListener(this);
Container stuff=getContentPane();
stuff.setLayout( new BoxLayout(stuff, BoxLayout.PAGE_AXIS) );
JPanel panelTop=new JPanel();
panelTop.setLayout(new GridLayout(1, 3, 300, 100));
panelTop.add(topLeft);
panelTop.add(topCenter);
panelTop.add(topRight);
JPanel panelCenter=new JPanel();
panelCenter.setLayout(new GridLayout(1, 3, 150, 100));
panelCenter.add(centerLeft);
panelCenter.add(centerCenter);
panelCenter.add(centerRight);
JPanel panelBottom=new JPanel();
panelBottom.setLayout(new GridLayout(1, 3, 300, 100));
panelBottom.add(bottomLeft);
panelBottom.add(bottomCenter);
panelBottom.add(bottomRight);
stuff.add(goSecond);
stuff.add(panelTop);
stuff.add(panelCenter);
stuff.add(panelBottom);
}
public static void main(String [] args)throws IOException
{
JFrame it=new Gui();
}
}
You are accessing images in different ways as shown below:
doge = new ImageIcon("dogeRotates.gif", null);
doge = new ImageIcon("./dogeIntensifies.gif", null);
Please check the image placement again.
If you are facing problem in accessing the images then have a look at my post
How to retrieve image from project folder?
Why don't you use simply GridLayout in this game of tic-tac-toe?
Find sample codes below
Java TicTacToe game winCondition?
Tic Tac Toe java
Sorry if its an obvious question.I have been trying to switch panels in the same window using cardlayout.But when i run my application nothing happens.
System.out.println(mntmBookingStatus);
the above statement does get printed on console.but not able to make out why cards arent switching when i click on menuitem "booking status" and "invoice entry".
public class StartDemo {
private JFrame frame;
private JPanel cards = new JPanel(new CardLayout());
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
StartDemo window = new StartDemo();
window.initialize();
window.frame.pack();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 772, 700);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//frame.setVisible(true);
// main menu
menuBar = new JMenuBar();
frame.setJMenuBar(menuBar);
// mainmenuoption-1
mnNewMenu = new JMenu("Entries");
menuBar.add(mnNewMenu);
// option-1 items
mntmBookingStatus = new JMenuItem("Booking Status");
mnNewMenu.add(mntmBookingStatus);
mntmBookingStatus.addActionListener(new MenuListenerAdapter());
mntmInvoiceEntry = new JMenuItem("Invoice Entry");
mnNewMenu.add(mntmInvoiceEntry);
mntmInvoiceEntry.addActionListener(new MenuListenerAdapter());
StartDemo demo = new StartDemo();
demo.addComponentToPane(frame.getContentPane());
}
public void addComponentToPane(Container pane) {
JPanel booking_status = new JPanel();
JPanel invoice_entry = new JPanel();
JPanel customer_ledger = new JPanel();
JPanel create_user = new JPanel();
try {
JPanelWithBackground panelWithBackground = new JPanelWithBackground(
"D:\\Kepler Workspace\\WEDemo\\images\\abc.jpg");
cards.add(panelWithBackground, "name_282751308799");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//the layout code for all the panels is written here.
//its to big to post here
cards.add(booking_status, BOOKINGPANEL);
cards.add(invoice_entry, INVOICEPANEL);
cards.add(customer_ledger, CUSTOMERLEDGER);
cards.add(create_user, CREATEUSER);
pane.add(cards, BorderLayout.CENTER);
}
public class MenuListenerAdapter implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
CardLayout c = (CardLayout) (cards.getLayout());
if (e.getSource() == mntmBookingStatus) {
c.show(cards, BOOKINGPANEL);
System.out.println(mntmBookingStatus);
} else if (e.getSource() == mntmInvoiceEntry) {
c.show(cards, INVOICEPANEL);
System.out.println(mntmInvoiceEntry);
}
}
This is my JPanelWithBackground class
public class JPanelWithBackground extends JPanel {
private Image backgroungImage;
private Image scaledBackgroundImage;
// Some code to initialize the background image.
// Here, we use the constructor to load the image. This
// can vary depending on the use case of the panel.
public JPanelWithBackground(String fileName) throws IOException {
backgroungImage = ImageIO.read(new File(fileName));
}
public void paintComponent(Graphics g){
super.paintComponent(g);
// Draw the backgroung image
g.drawImage(backgroungImage, 0, 0,getWidth(),getHeight(),null);
}
It's these two lines right here
StartDemo demo = new StartDemo();
demo.addComponentToPane(frame.getContentPane());
Since your initialize() method isn't static I think it's safe to assume that you instantiate youe StartDemo again in the main method. In that case, the above code truly is your problem and would totally explain why it doesn't work. Just do this
//StartDemo demo = new StartDemo(); <-- get rid of this.
addComponentToPane(frame.getContentPane());
Tested with code additions only to get it running. Also please not my comments above. setVisible(true) generally is the last thing you should do after adding all components.
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class StartDemo {
private JFrame frame;
private JPanel cards = new JPanel(new CardLayout());
JMenuBar menuBar;
JMenu mnNewMenu;
JMenuItem mntmBookingStatus;
JMenuItem mntmInvoiceEntry;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
new StartDemo().initialize();
}
});
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 772, 700);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// main menu
menuBar = new JMenuBar();
frame.setJMenuBar(menuBar);
// mainmenuoption-1
mnNewMenu = new JMenu("Entries");
menuBar.add(mnNewMenu);
// option-1 items
mntmBookingStatus = new JMenuItem("Booking Status");
mnNewMenu.add(mntmBookingStatus);
mntmBookingStatus.addActionListener(new MenuListenerAdapter());
//StartDemo demo = new StartDemo();
addComponentToPane(frame.getContentPane()); mntmInvoiceEntry = new JMenuItem("Invoice Entry");
mnNewMenu.add(mntmInvoiceEntry);
mntmInvoiceEntry.addActionListener(new MenuListenerAdapter());
frame.setVisible(true);
}
public void addComponentToPane(Container pane) {
JPanel booking_status = new JPanel();
JPanel invoice_entry = new JPanel();
//JPanel customer_ledger = new JPanel();
//JPanel create_user = new JPanel();
try {
JPanelWithBackground panelWithBackground = new JPanelWithBackground(
"/resources/stackoverflow5.png");
cards.add(panelWithBackground, "name_282751308799");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
cards.add(booking_status, "booking");
cards.add(invoice_entry, "invoice");
//cards.add(customer_ledger, CUSTOMERLEDGER);
//cards.add(create_user, CREATEUSER);
pane.add(cards, BorderLayout.CENTER);
}
class JPanelWithBackground extends JPanel {
Image img;
public JPanelWithBackground(String path) throws IOException {
img = ImageIO.read(getClass().getResource(path));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
}
public class MenuListenerAdapter implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
CardLayout c = (CardLayout) (cards.getLayout());
if (e.getSource() == mntmBookingStatus) {
c.show(cards,"booking");
System.out.println(mntmBookingStatus);
} else if (e.getSource() == mntmInvoiceEntry) {
c.show(cards, "invoice");
System.out.println(mntmInvoiceEntry);
}
}
}
}