I've been trying to add JTable to my JPanel, yet it doesn't appear there. I've searched through other questions, but solutions proposed there didn't help me.
The function below is a part of a class which extends JFrame. "repaint" is a BufferedImage, "imageLabel" is JLabel and "image" is ImageIcon.
public void showTable() {
try {
repaint = ImageIO.read(new File("filename.jpg"));
} catch (IOException e) { }
Graphics g = repaint.createGraphics();
g.setFont(font);
g.setColor(black);
String[] columnsName = {"id","text"};
Object[][] data = {{new Integer(1),"text one"},{new Integer(2),"text two"}};
JTable table = new JTable(data, columnsName);
JScrollPane tableContainer = new JScrollPane(table);
image = new ImageIcon(repaint.getScaledInstance(sizeX,sizeY, Image.SCALE_SMOOTH));
imageLabel.setIcon(image);
imageLabel.add(tableContainer,BorderLayout.CENTER);
getContentPane().add(imageLabel);
pack();
setVisible(true);
repaint();
revalidate();
}
What I want to achieve is to display table over loaded image.
Thanks in advance for Your help :)
Give your JLabel a layout manager, here BorderLayout via setLayout(new BorderLayout()).
Don't get your Graphics object via getGraphics() as it returns an object that is short-lived. To see for yourself, minimize your program and then restore it and watch your drawing disappear. Instead, draw in the paintComponent(...) override method.
Read the Swing tutorials for greater detail on how to do these things, especially the layout manager tutorial.
I'm not sure if I understood correctly, but you want to put a table and an image below it, right?
I would create a JPanel with BorderLayout, put the image (JLabel) on the bottom (Page end) and the table (that scrollPanel you created) on the center.
If you need help with adding items to JPanel with BorderLayout, see how to do it on this Tutorial:
http://docs.oracle.com/javase/tutorial/uiswing/layout/border.html
I hope it helps.
Thanks for all the hints so far :) They were really useful. I know that I might be doing some things in a not elegant way, but I'm still learning, will try to improve :)
The given hints and some more searching lead me to such code :
public void showTable()
{
try
{
repaint = ImageIO.read(new File("filename.jpg"));
}catch (IOException e) {
}
Graphics g = repaint.createGraphics();
g.setFont(font);
g.setColor(black);
String[] columnsName = {"id","text"};
Object[][] data = {{new Integer(1),"text one"},{new Integer(2),"text two"}};
JTable table = new JTable(data, columnsName);
table.setOpaque(false);
JScrollPane tableContainer = new JScrollPane(table);
tableContainer.setBorder(BorderFactory.createEmptyBorder());
tableContainer.setOpaque(false);
tableContainer.getViewport().setOpaque(false);
image = new ImageIcon(repaint.getScaledInstance(sizeX,sizeY, Image.SCALE_SMOOTH));
imageLabel.setIcon(image);
imageLabel.setLayout(new BorderLayout());
imageLabel.add(tableContainer, BorderLayout.SOUTH);
repaint();
revalidate();
}
Which works fine for me :)
Once again thanks all for the help :)
Related
I have a JScrollPanel and a JPanel added to it. I would like to draw to the JPanel and make the scrollbars of the JScrollPane appear whenever the drawing exceeds the size of the panel and be able to scroll the drawing both vertically and horizontally.
I have tried consulting with various forums and the official docs and tried a few things (setting the borders, the preferred size, etc.) but none seems to yield the desired effects.
I have a JFrame (with GridBagLayout, btw.) :
JFrame frame1 = new JFrame("Application");
frame1.setVisible(true);
frame1.setMinimumSize(new Dimension(580,620));
frame1.setResizable(false);
frame1.setLocationRelativeTo(null);
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
The relevant components are :
JPanel panel1 = new JPanel();
JScrollPane scrollPane = new JScrollPane(panel1);
frame1.add(scrollPane, gbc_panel1); //added with layout constraints
JPanel :
panel1.setBackground(Color.BLACK);
panel1.setPreferredSize(new Dimension(500,500));
panel1.setMinimumSize(new Dimension(360,360));
panel1.setMaximumSize(new Dimension(1000,1000));
JScrollPane :
scrollPane.setAutoscrolls(true);
The relevant code from the action event
of a button that does the drawing :
Graphics g;
g = panel1.getGraphics();
panel1.paint(g);
g.setColor(new Color(0,128,0));
/* this is followed by some more code that
does the drawing of a maze with g.drawLine() methods */
The code does the drawing perfectly, I just can't seem to figure it out how to make the scrolling and dynamic resizing happen.
I would appreciate any helpful comments or remarks!
Thank you!
Ultimately rewriting the paint method did the trick as #MadProgrammer suggested. I was just hoping that I could do the painting without having to define my custom JPanel class, but looks like it doesn't work that way.
The custom class looks like this:
class Drawing extends JPanel {
int mazeSize;
public Drawing(JTextField jtf)
{
try {
this.mazeSize = Integer.parseInt(jtf.getText());
}
catch (Exception e)
{
JOptionPane.showMessageDialog(this, "ERROR! Invalid size value!");
}
} // the constructor gets the size of the drawing from a textField
public Dimension getPreferredSize() {
return new Dimension(mazeSize*10,mazeSize*10);
} //getPreferredSize - this method is used by the scroll pane to adjust its own size automatically
public void drawMaze (Graphics g)
{
/* some irrelevant code that does the desired drawing to the panel by calling g.drawLine()*/
} // drawMaze method that does the de facto drawing
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
drawMaze(g);
}// paintComponent() #Override method - this was the tricky part
}//Drawing JPanel subclass
It is also worth noting (if some noob like myself happens to stumble upon this question), that after instantiating the new JPanel subclass in the action event, I had to add it to the JScrollPanel in the following way, instead of just simply using its add() method:
Drawing drawPanel = new Drawing(textfield1);
scrollPane.getViewport().add(drawPanel);
Again, thanks for the suggestion!
Once finished with the program (a random maze generator that uses a recursive backtracking algorithm), I will make the source code available at my github profile.
We're about to create an online based Space Invaders-game with implemented graphics. I've been reading about JFrames, JPanels and JLabels in order to create a window with a grid where the ships and monsters will be placed in.
So, here's the thing, I've been looking through the different layouts that exists, but nothing really seems to fit our purpose. I would like a simple JFrame with the possibility of placing JLabel-objects on a certain position (with setBounds(), setLocation() or something similar). This requires setLayout(null) which I've heard isn't a good solution? I was thinking of having objects in a fixed 30x30px size, and a fixed window size of 600x600px (giving me a grid of 20*20).
Anyhow, I've been trying to get it to work with setLayout(null), but without any results. If I apply a layout, say FlowLayout, the ship is visible, but stuck in either LEFT, CENTER or MIDDLE.
public class GUI extends JFrame {
JPanel p = new JPanel(null);
public GUI() {
try{
this.setContentPane(new JLabel(new ImageIcon(ImageIO.read(new File("graphics/bg.png")))));
}catch(IOException e) {
System.out.println("Image does not exist");
}
this.setLayout(null);
this.setResizable(false);
this.setSize(600,600);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setVisible(true);
}
public void placeShip1() {
ImageIcon ship2 = new ImageIcon("graphics/ship2.png");
JLabel imageLabel = new JLabel(ship2);
imageLabel.setBounds(200,200,30,30);
p.add(imageLabel);
p.setOpaque(false);
p.setSize(600, 600);
this.add(p);
this.setVisible(true);
}
}
I really can't see why it doesn't work. I mean, all I want is my JFrame with a background image and with an object on a certain position, but instead the object doesn't show at all.
The main reason for wanting to use setLayout(null) is because I was thinking of using a method translating our grid coordinates to the JFrame, simply mapping each coordinate to respective cell.
I am trying to simply draw an image on a jframe by using an Imageicon. However when I run it its just blank. Heres my code...
public final class PICS
{
public static final void main(String... aArgs)
{
JFrame frame = new JFrame("IMAGE");
frame.setVisible(true);
frame.setSize(500,500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ImageIcon image = new ImageIcon("image/pic1.jpg");
JLabel label = new JLabel("", image, JLabel.CENTER);
JPanel panel = new JPanel(new BorderLayout());
panel.add( label, BorderLayout.CENTER );
}
}
I am very new to everything java including this website, so I apologize if im missing something. Also im using Eclipse, and are there specific formats you can use for images, or is there a limit to size?
I am very new to everything java including this website
Then I would suggest you start by reading tutorials especially the Swing tutorial. Maybe the section on How to Use Icons would be a good place to start. The example code will show you how to use Icons as well as how to structure your program so that the GUI code is executed on the EDT. The tutorial on Concurrency will explain why the EDT is important.
Two things.
First, make setVisible the last call AFTER you have built your frame and it's contents...ie
JFrame frame = new JFrame("IMAGE");
frame.setSize(500,500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ImageIcon image = new ImageIcon("image/pic1.jpg");
JLabel label = new JLabel("", image, JLabel.CENTER);
JPanel panel = new JPanel(new BorderLayout());
panel.add( label, BorderLayout.CENTER );
// Make me last
frame.setVisible(true);
Two, make sure that the image/pic1.jpg exists and is the directory image under the current execution context.
If the image is a embedded resource (lives within the Jar or your application), then you need to supply a URL to the image instead of a String as ImageIcon treats String as a file name...
ImageIcon image = new ImageIcon(PICS.class.getResource("image/pic1.jpg"));
For example.
I would encourage you to use JFrame#pack over JFrame#setSize as it will resize the frame to the preferred size of your content...
I would also encourage you to take the time to read through Code Conventions for the Java Programming Language, Initial Threads.
I would also encourage you to use ImageIO over ImageIcon as it will, at least, throw an Exception if something goes wrong
Updated, testing image path
Try adding this to the constructor of your PICS class. This will, at least, tell you where the image isn't...
try {
ImageIO.read(PICS.class.getResource("image/pic1.jpg"));
} catch (IOException ex) {
System.out.println("Not in image/pic1.jpg");
}
try {
ImageIO.read(PICS.class.getResource("/image/pic1.jpg"));
} catch (IOException ex) {
System.out.println("Not in /image/pic1.jpg");
}
try {
ImageIO.read(PICS.class.getResource("resources/image/pic1.jpg"));
} catch (IOException ex) {
System.out.println("Not in resources/image/pic1.jpg");
}
try {
ImageIO.read(PICS.class.getResource("/resources/image/pic1.jpg"));
} catch (IOException ex) {
System.out.println("Not in /resources/image/pic1.jpg");
}
I've spent almost 2 hours now on it but I can't get it working.
I just want to paint a image on a JPanel.
I want to paint the imageChaser image on the arena JPanel.
But it's not displaying.
What am i doing wrong?
Heres my code :
public class GuiGameBoard extends JPanel {
//import stuff
private JPanel arena;
BufferedImage imageChaser;
BufferedImage imageChaserSelected;
BufferedImage imageTarget;
public GuiGameBoard() {
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
arena = new JPanel();
arena.setPreferredSize(new Dimension(500, 500));
arena.setBackground(Color.BLACK);
this.add(arena);
try
{
File inputChaser = new File("resources\\chaser.png");
imageChaser = ImageIO.read(inputChaser);
File inputChaserSelected = new File("resources\\chaser_selected.png");
imageChaserSelected = ImageIO.read(inputChaserSelected);
File inputTarget = new File("resources\\target.png");
imageTarget = ImageIO.read(inputTarget);
}
catch (IOException ie)
{
System.out.println("Error:"+ie.getMessage());
}
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(imageChaser, 0, 0, null);
}
}
I think the problem is, that your hiding your picture by adding the JPanel arena to your GuiGameBoard class, which already is a JPanel.
But without an SSCCE, giving an adequate answer isn't possible...
I think you forget a 'top-level container' e.g. JFrame.
Take a look at this example
example code.
For more information click here
Can someone work out why my JScrollPane is not working. Perhaps something I may have missed. I realize this might be silly without any more context than what I've shown but please ask and I shall be happy to provide more.
public ApplicationFrame(String title, int x, int y, int width, int height) {
// Constructor for the ApplicationFrame, no implicit Construc.
setTitle(title);
setResizable(true);
setBounds(x, y, width, height);
setLayout(new BorderLayout());
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setIconImage(new ImageIcon(getClass().getResource("resources/topLeft.png")).getImage());
topMostMenuBar = new TopMenuBar(this);
setJMenuBar(topMostMenuBar.getMyJMenuBar());
paneEdge = BorderFactory.createLineBorder(Color.gray);
blackline = BorderFactory.createLineBorder(Color.black);
this.frameContent = new ApplicationPanel() {
//#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(TI, 0, 0, null);
}
};
mainImageScrollPane = new JScrollPane(frameContent);
statusPanel = new ApplicationPanel(new Color(0xfff0f0f0));
leftPanel = new ApplicationPanel(new Color(0xfff0f0f0));
testPanel = new ColorPanel(new Color(0xfff0f0f0));
testPanel.setPreferredSize(new Dimension(50,300));
add(mainImageScrollPane, BorderLayout.CENTER );
add(statusPanel, BorderLayout.SOUTH);
add(leftPanel, BorderLayout.WEST);
Container visibleArea = getContentPane();
visibleArea.add(frameContent);
setVisible(true);
do {
loadImageIn();
} while (!initLoadSuccess);
initButtons();
leftPanel.add(testPanel, BorderLayout.SOUTH);
} // end Constructor **
This is a big piece of code so I'm not sure how to make an SSCCE out of it. What youre looking at is the constructor to my subclass of a JFrame, which holds 3 panels. The ApplicationPanel is at this point just a JPanel. The loadImageIn() method opens a filechooser and then loads the chosen image which is painted onto frameContent. The image displays fine, everything works, except when I resize the window, there are no scrollbars.
You have this line, which adds the ApplicationPanel to the visibleArea...
visibleArea.add(frameContent);
Maybe you actually mean this, which adds the JScrollPane to the visibleArea (and the JScrollPane already contains the ApplicationPanel)...
visibleArea.add(mainImageScrollPane);
When you call new JScrollPane(frameContent), it doesn't do anything to the panel inside it, it just adds a wrapper around the outside. So, if you want the ability to scroll, you need to refer to the JScrollPane wrapper, rather than the panel itself.
You didn't specify any size for your frameContent. Is it intentional?
Additionally your frameContent is later on being added to visibleArea. Meaning no longer in the mainImageScrollPane JScrollPane
Maybe you wanna have:
visibleArea.add(mainImageScrollPane);, but you need to set your panel size
mainImageScrollPane.setViewportView(<component_to_be_scrollable>);