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
Related
I am trying to draw an image to a JPanel which in turn is added to a JFrame, see here:
JFrame screen;
public void welcome(){
screen = new JFrame("Welcome");
screen.setVisible(true);
screen.pack();
screen.setBackground(Color.darkGray);
screen.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
// in the original code there is series of methods here that eventually calls the drawBoard() method
public void drawBoard(){
try {
final BufferedImage gboard = ImageIO.read(new File("cutsomGameBoard.jpg"));
final BufferedImage featPanel = ImageIO.read(new File("extraPanel.png"));
board = new JPanel(){
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(gboard, 0, 0, this);
}
};
extra = new JPanel(){
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(featPanel, 0, 0, this);
}
};
board.setSize(480, 480);
extra.setSize(480, 320);
}
catch (IOException e) {
e.printStackTrace();
}
}
gameScreen.add(toolbar, BorderLayout.PAGE_START);
gameScreen.add(board, BorderLayout.EAST);
gameScreen.add(extra, BorderLayout.WEST);
gameScreen.setVisible(true);
screen.add(gameScreen);
}
My problem is that when running the code, only a small corner of the buffered image is visible and I am not sure if it is a problem with the frame layout, the panel size or the drawImage method arguments, ideas?
P.S. The output: screenshot of java window
You didn't override the getPreferredSize() method of your custom component so the default size is basically (10, 10) which is the size of a panel using a FlowLayout with no added components.
Don't use a JPanel to display an image. Or if you do want to use a JPanel then you need to implement the getPreferredSize() method to return the size of your image.
The easiest solution is to just use a JLabel with an ImageIcon.
Read the section from the Swing tutorial on How to Use Icons for more information and working examples.
I have read a lot of answers about this problem but I can't manage to find my error even on a simple code. Here is the problem : I'd like to draw an Image in a JLabel which is in a JPanel, but the paintComponent() method of the JLabel isn't called.
Here is the code :
The ImagePainter class should draw an image
public class ImagePainter extends JLabel{
private Image image;
public ImagePainter(){
try {
image = ImageIO.read(new File("src/testgui/image.png"));
} catch (IOException exception) {
exception.printStackTrace();
}
}
#Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(image, 0, 0, null);
System.out.println("in paintComponent");
}
}
Here is a standard JFrame. I took care to add the JPanel to the contentPane
public class Display extends JFrame{
public Display(){
JPanel jp = new JPanel();
ImagePainter i = new ImagePainter();
getContentPane().add(jp);
jp.add(i);
jp.repaint();
setSize(800, 800);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
And finally the main. I instanciate Display on the EDT like everyone tell to do :
public class Main {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable(){
#Override
public void run(){
Display d = new Display();
}
});
}
}
Finally, I observed that if I directly add the ImagePainter to the contentPane, the image is drawn correctly. It's probably a stupid error but I spend literally hours trying to find it and really can't see it. Thank you in advance !
The label does not account for the preferred size of the image when the image is custom painted! The panel by default has a flow layout. A flow layout does not stretch components to fit. So that label would have size of 0 x 0 pixels. You can confirm that by adding a visible border to the label.
But given the image is displayed in a label, why not just set the image as the icon of the label?
Also, the jp.repaint() statement in the Display constructor is useless, since you have not yet set the frame visible.
I'm trying to add a JScrollPane to an JPanel from a separate class. And thanks to some questions, which were asked so far, I could help myself create them. But my problem is still a little bit special.
I want to display an image on a JPanel and if the image is to large for the panel, I want to add scrollbars. But the scrollbars won't appear.
(When I set the ScrollPaneConstants to ****_SCROLLBAR_ALWAYS the frame of the bar appears, but without the bars to scroll).
I guess i have to connect the imagesize with the bars, so that they appear?
Some pieces of my code:
MainWindow
public class Deconvolutioner extends JFrame
{
Draw z;
Picturearea picturearea;
class Draw extends JPanel
{
public void paint(Graphics g)
{
}
}
public Deconvolutioner()
{
setTitle("Deconvolutioner");
setLocation(30,1);
setSize(1300,730);
super.setFont(new Font("Arial",Font.BOLD,11));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
FlowLayout flow = new FlowLayout(FlowLayout.CENTER);
this.setLayout(flow);
picturearea = new Picturearea();
picturearea.setLayout(new GridBagLayout());
JScrollPane scrollPane = new JScrollPane(picturearea,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setPreferredSize(new Dimension(1000, 664));
getContentPane().add(scrollPane, flow); // add scrollpane to frame
add(z = new Draw());
setVisible(true);
}
}
JPanel Class
public class Picturearea extends JPanel
{
BufferedImage image;
int panelWidth, panelHeight, imageWidth, imageHeight;
public Picturearea()
{
setBackground(new Color(210,210,210));
setBorder(LineBorder.createBlackLineBorder());
setVisible(true);
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
public void setPicture(BufferedImage picture)
{
try
{
image = picture;
}
catch (Exception e)
{
System.err.println("Some IOException accured (did you set the right path?): ");
System.err.println(e.getMessage());
}
repaint();
}
}
Thanks for your time.
The problem is that the JScrollPane has no way to know if it should display scroll bars or not, since the Picturearea it contains doesn't tell anything about its preferred size (or rather, it returns the preferred size based on its layout and on the components it contains. But since it doesn't contain any component, the returned preferred size is probably (0, 0)).
I would simply use a JLabel instead of the custom Picturearea class. A JLabel can display an image just fine, and it returns the appropriate Dimension when asked for its preferred size.
You can create a JLabel first and then add the Label to JPanel picturearea before creating instance for JScrollPane .
Have a try and it will work.
Example code is as follows:
JLabel imageLabel = new JLabel(new ImageIcon("d:\\099.jpg"));
picturearea.add(imageLabel);**
JScrollPane scrollPane = new JScrollPane(picturearea,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
I have a GUI with a created JPanel and a "Start" button. All I need is when I click "Start", an image will be loaded and appear on that JPanel.
But my problem is when I click "Start", nothing happens.
Can anyone help me fix this problem?
Here is my code:
private BufferedImage image;
public class ImagePanel extends JPanel {
public ImagePanel() {
try {
image = ImageIO.read(new File("C:\\Users\\HienTran\\Desktop\\Miranda-Kerr-16-240x320.jpg"));
} catch (IOException ex) {
// handle exception...
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, null);
}
}
private void startBtnActionPerformed(java.awt.event.ActionEvent evt) {
stopBtn.setEnabled(true);
startBtn.setEnabled(false);
imageArea.add(new ImagePanel()); // imageArea is the JPanel in the GUI
}
When I replace 2 lines of imageArea by creating a new JFrame as below, that JFrame shows up with the image I added.
private void startBtnActionPerformed(java.awt.event.ActionEvent evt) {
stopBtn.setEnabled(true);
startBtn.setEnabled(false);
JFrame test = new JFrame("Window");
test.add(new ImagePanel());
test.setSize(image.getWidth(), image.getHeight() + 30);
test.setVisible(true);
}
When you add components to a visible GUI the basic code is:
panel.add(...);
panel.revalidate();
panel.repaint();
However, that probably won't help because by default a JPanel uses a FlowLayout and a FlowLayout respects the size of the component. Your ImagePanel will have a size of (0, 0) since you did not override the getPreferredSize() method.
There is no need to create a custom panel to paint your image. Just use a JLabel with an Icon then you let the label worry about the size. Don't reinvent the wheel.
I suggest you read the Swing tutorial for the basics. Maybe the section on How to Use Labels would be a good place to start. The tutorial will also show you a better way to design your class wo that you follow Swing guidelines.
First fix a bit:
try {
image = ImageIO.read(new File("C:\\Users\\HienTran\\Desktop\\Miranda-Kerr-16-240x320.jpg"));
} catch (IOException ex) {
ex.printStacktrace(); // see if there is an exception, like not finding or something
}
than:
If you add a panel, than need a layout refresh and a gui refresh:
imageArea.add(new ImagePanel());
imageArea.revalidate(); // refresh layout
imageArea.repaint(); // shedule painting
whats wrong with my code? I just want to have a Picture in my Window...
//class ImagePanel:
public class ImagePanel extends JPanel {
private static final long serialVersionUID = -7664761101121497912L;
public Image i;
public ImagePanel(Image i) {
this.i = i;
}
#Override
public void paintComponents(Graphics g) {
super.paintComponent(g);
g.drawImage(this.i, 0, 0, null);
}
}
//class Main
public class Main extends JFrame {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(1024, 768);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ImagePanel panel = null;
try {
panel = new ImagePanel(ImageIO.read(new File("D:/test.JPG")));
} catch (IOException e) {
e.printStackTrace();
}
frame.getContentPane().add(panel);
frame.setVisible(true);
}
}
There is just a Window without a picture :(
Whats the problem? And is there an easy way to set size of the window == picture size?
Thank you!
You must override paintComponent(Graphics g) instead of paintComponents(Graphics g).
The best solution is to use a JLabel. Don't reinvent wheel. There is no need for you to do custom painting.
But if you do custom painting then you need to override the getPreferredSize() method to be the size of the image so the layout manager can do their job.
please read this tutorials about Icon in Swing and your Image would by placed to the JLabel but with same way/funcioanlities as to the JPanel
I not at all familiar with Java panes, but don't you need to set the size of ImagePanel before you add it to the content pane.