Displaying an Image in java - java

I am having problems displaying an image on a frame. When the picture is displayed the top left corner doesn't go to the (0,0) specified, also the background of the window takes on visual components of whatever was behind the window when I first ran it. Does anybody know what's wrong? Thanks in advance-
import java.awt.image.ImageObserver;
import java.io.File;
import javax.imageio.*;
import javax.swing.*;
public class Window extends JFrame{
//the pictures
Image testImage = null;
Image backPic = null;
//constructor
Window(){
super("window");
this.startWindow();
}
public void startWindow(){
Image customIcon = Toolkit.getDefaultToolkit().getImage("iconImage.gif");
testImage = Toolkit.getDefaultToolkit().getImage("tester.gif");
backPic = Toolkit.getDefaultToolkit().getImage("black.png");
setSize(700,600);
setIconImage(customIcon);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setResizable(false);
setLocationRelativeTo(null);
}
public void paint(Graphics g){
g.drawImage(testImage,0,0,null);
}
}

The problem is that your testImage is not yet fully loaded when paint() is called. To fix this, you can invoke this instead:
g.drawImage(testImage,0,0,this);
But my preferred approach would be to use a JLabel and let it handle the image drawing. I also strongly recommend to not override JFrame.paint() (and if you do, at least call super.paint(g)). If you really want to draw an image yourself, extend JComponent and override paintComponent()

So my advice to you use JLabels for example to show Images, it's the simpliest way you can sure use. I created similar basic project that demonstate this way.
/**
* #author Sajmon
*/
package com.sajmon.window;
import java.awt.Container;
import java.awt.FlowLayout;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Window extends JFrame {
private JLabel pictureLabel;
private Container controls;
public Window() {
super("window");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setLocationRelativeTo(null);
this.setSize(300, 300);
this.startWindow();
}
private void startWindow() {
controls = new Container();
controls = getContentPane();
controls.setLayout(new FlowLayout());
pictureLabel = new JLabel(new ImageIcon("picture.png"));
controls.add(pictureLabel);
}
}
And Main method for run application.
/**
*
* #author Sajmon
*/
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
Window w = new Window();
w.setVisible(true);
}
});
}
}
Note: If you working with Swing, you should starting your application with Runnable interface. This way is generally recommended.
Hope it helps.

Related

Java JLabel background color not working?

I'm learning how to create application in Java.
I'm having trouble getting the JLabel to have a background color whilst the JPanel is white, behind it. Also, is there a way to resize the JPanel to half of what the JFrame is?
Any help would be very much appreciated. Thank you.
package PracticeOne;
import java.awt.BorderLayout;
public class PracticeOne {
public static void main(String[] args) {
Frame container = new Frame();
Panel box = new Panel();
Label txt = new Label();
box.add(txt);
container.add(box, BorderLayout.CENTER);
}
}
package PracticeOne;
import javax.swing.JFrame;
public class Frame extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
Frame(){
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(500, 500);
this.setVisible(true);
this.setLocationRelativeTo(null);
this.setTitle("Testing this out");
}
}
package PracticeOne;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JPanel;
public class Panel extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
public Dimension d = new Dimension(100,100);
Panel(){
this.setSize(d);
this.setAlignmentX(CENTER_ALIGNMENT);
this.setBackground(Color.WHITE);
}
}
package PracticeOne;
import java.awt.Color;
import javax.swing.JLabel;
public class Label extends JLabel {
/**
*
*/
private static final long serialVersionUID = 1L;
Label(){
this.setSize(50, 50);
this.setText("ya boy is working here");
this.setForeground(Color.BLACK);
this.setBackground(Color.ORANGE);
}
}
I'm having trouble getting the JLabel to have a background color whilst the JPanel is white
You need to call setOpaque(true); in your JLabel
Also, is there a way to resize the JPanel to half of what the JFrame is?
You could use a GridLayout, and place 2 JPanels in it, that way, you're going to have 2 JPanels using half the size of your JFrame each.
Also, rename your classes, Panel belongs to the name of a class in AWT, same for Frame and Label, this might confuse your (and whoever reads your code).
Never extend JFrame, instead build your GUI based on JPanels. See extends JFrame vs creating it inside of class and The use of multiple JFrames, Good / Bad practice? The general consensus says it's bad.
Also you should also check Should I avoid the use of setPreferred|Maximum|MinimumSize() in Swing? Again, yes, you should and instead override the getPreferredSize() method.
Don't forget to place your program on the Event Dispatch Thread (EDT) by changing your main() method as follows:
public static void main(String[] args) {
//Java 8 with lambda expressions
SwingUtilities.invokeLater(() ->
//Your code here
);
//Java 7 and below (Or 8 without lambda expressions)
SwingUtilities.invokeLater(new Runnable() {
//Your code here
});
}
Now, with all the above recommendations, your code should now look like this:
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class HalfSizePanelWithLabelInDifferentColor {
private JFrame frame;
private Container contentPane;
private JPanel pane;
private JPanel pane2;
private JLabel label;
private static final Dimension dim = new Dimension(100, 100);
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new HalfSizePanelWithLabelInDifferentColor().createAndShowGui());
}
public void createAndShowGui() {
frame = new JFrame(getClass().getSimpleName());
contentPane = frame.getContentPane();
pane = new JPanel() {
#Override
public Dimension getPreferredSize() {
return dim;
}
};
pane2 = new JPanel();
pane.setOpaque(false);
pane2.setOpaque(false);
pane.setBorder(BorderFactory.createLineBorder(Color.RED));
pane2.setBorder(BorderFactory.createLineBorder(Color.BLUE));
label = new JLabel("Hello World!");
label.setBackground(Color.GREEN);
label.setOpaque(true);
contentPane.setLayout(new GridLayout(2, 1));
pane.add(label);
contentPane.add(pane);
contentPane.add(pane2);
contentPane.setBackground(Color.WHITE);
frame.setContentPane(contentPane);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
And your output would be like this:
Note that I added some colored borders to show where a pane starts and ends and where the other one starts and ends

I'm lost in the JPanel, JFrame update and action listening

Good day everyone! I just got back into programming, and I'm facing some problem with the construction of my code. What I'm trying to do is a menu for a future application that could help me and my friends when we play a certain board game.
So right now, I'm having difficulty to figure out how I should structure my code. I have 3 class planned so far. the Main class, which create a JFrame. a MainFrame class which help the main setup the frame, and finally the third class is MainPanel, which display the proper JPanel on the frame depending on the state of the program.
The plan JPanel classes are:
a menu Panel, with 3 button on it: New, Load and Exit.
a loading Panel, which just display "Loading" while the application load stuff (will be use when someone click New)
a loadBoard Panel, which display the list of created board (when someone click Load)
I'm having 2 issue right now:
Where do I fit the code to monitor the Key event (such as KeyListener on the frame, so independently of where I am at in the program, the program Exit when I press the Esc key.)
How do I make sure the repaint() is handle properly? I have a problem where the Label "Loading" change location when I resize the window.
I know my code ain't construct ideally, that's why I'm posting this thread. I would like to better understand how to setup the code to have a similar result of what I have right now, but well construct.
This is my code:
MAIN Class
package test.project
import java.awt.Dimension;
public class Main
{
public static void main(String[] args)
{
Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
javax.swing.SwingUtilities.invokeLater(() ->
{
MainFrame theWindow = new MainFrame("Test",screenSize);
theWindow.setLocationRelativeTo(null);
theWindow.getContentPane().add(new MenuPanel(theWindow,theWindow.getSize()));
});
}
}
MAINFRAME Class
package test.project;
import java.awt.Dimension;
import javax.swing.JFrame;
public class MainFrame extends JFrame
{
#SuppressWarnings("LeakingThisInConstructor")
public MainFrame(String windowName, Dimension theSize)
{
setTitle(windowName);
setSize(theSize.width/2,theSize.height/2);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
}
MAINPANEL Class
package test.project;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
public class MainPanel extends JPanel
{
JFrame theHolder;
public MainPanel(JFrame holder, Dimension theSize)
{
theHolder = holder;
setSize(theSize);
}
}
class MenuPanel extends MainPanel implements ActionListener
{
JButton newButton = new JButton("NEW");
JButton loadButton = new JButton("LOAD");
JButton exitButton = new JButton("EXIT");
#SuppressWarnings("LeakingThisInConstructor")
public MenuPanel(JFrame holder, Dimension theSize)
{
super(holder, theSize);
setLayout(new GridLayout(0,1));
SetButton(this);
setVisible(true);
theHolder.repaint();
}
private void SetButton(JPanel thePanel)
{
newButton.addActionListener(this);
loadButton.addActionListener(this);
exitButton.addActionListener(this);
thePanel.add(newButton);
thePanel.add(loadButton);
thePanel.add(exitButton);
}
#Override
public void actionPerformed(ActionEvent e)
{
if(e.getSource().equals(newButton))
{
theHolder.getContentPane().remove(this);
theHolder.getContentPane().add(new LoadingPanel(theHolder,theHolder.getSize()));
theHolder.repaint();
}
if(e.getSource().equals(loadButton))
{
}
else if(e.getSource().equals(exitButton))
{
System.exit(0);
}
}
}
class LoadingPanel extends MainPanel
{
JLabel loadingLabel = new JLabel("LOADING");
#SuppressWarnings("LeakingThisInConstructor")
public LoadingPanel(JFrame holder, Dimension theSize)
{
super(holder, theSize);
setLayout(new GridLayout(0,1));
SetLabel(this);
setVisible(true);
theHolder.repaint();
}
private void SetLabel(JPanel thePanel)
{
thePanel.add(loadingLabel);
loadingLabel.setSize(thePanel.getSize());
loadingLabel.setHorizontalAlignment(SwingConstants.CENTER);
loadingLabel.setVerticalAlignment(SwingConstants.CENTER);
}
}

JFileChooser in front of fullscreen Swing application

I know there are some topics relative to this question (mainly this unanswered one and this one which is not handling full screen app).
I basically tried every combination of first topic sample and available methods (requestFocus, requestFocusInWindow, ...) but JFileChooser is always displaying behind the fullscreen app. I tried to change filechooser's parent too (setting it to null, itself or the parent frame) with no more success.
Have anyone a working example of this not-that-much-particular use case? Or is there a workaround to let user select files in a fullscreen app?
Unfortunately I can't say how you realised the implementation of the fullscreen app. But I tried a few things and came up with this:
import java.awt.Color;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class Gui extends JFrame {
public Gui() {
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
//this.setSize(java.awt.Toolkit.getDefaultToolkit().getScreenSize());
// Set some charateristics of the frame
this.setExtendedState(Frame.MAXIMIZED_BOTH);
this.setBackground(Color.black);
this.setUndecorated(true);
JButton a = new JButton("PRESS ME!");
a.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
JFileChooser fc = new JFileChooser();
fc.showOpenDialog(getParent());
}
});
this.add(a);
this.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Gui();
}
});
}
}
Pay attention to the fact, that I created a new JFileChooser with the parent of the current JFrame as parameter.
EDIT:
I now even tried to set
java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().setFullScreenWindow(new Gui());
and without the
this.setUndecorated(true);
it worked for me (got a nice fullscreen view and the JFileChooser was in the front). I believe the problem with the window decoration is linked to my window manager (I'm using linux with gnome).
Hopefully this solution works for you, if not:
Could you explain a little bit more, how you create the fullscreen app?
I would suggest instead of using using a Popup, just embed the JFileChooser into your application. It doesn't really make sense to have popups in a windowless application (Personally, I don't like popups much anyways).
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FullScreenApp {
public static void main(String[] args) {
final JFrame frame = new JFrame();
frame.setTitle("Frame");
frame.setSize(800, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GraphicsDevice device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
device.setFullScreenWindow(frame);
device.setDisplayMode(new DisplayMode(800, 600, 32, 60)); // Ugh.
frame.setVisible(true);
final Box panel = Box.createVerticalBox();
JButton btn = new JButton();
btn.setText("Button");
panel.add(btn);
frame.add(panel);
final CustomFileChooser chooser = new CustomFileChooser(panel);
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
chooser.show();
}
});
}
public static class CustomFileChooser extends JFileChooser{
/** Node this chooser should be added to.
* There's likely a better way of doing this,
* but it was convenient for a quick example */
Container parent;
public CustomFileChooser(Container parent){
super();
this.parent = parent;
//Make configurations for your file chooser
setApproveButtonText("Open");
}
#Override
public void approveSelection(){
super.approveSelection();
//Perform accept action here
System.out.println(getSelectedFile().getAbsolutePath());
parent.remove(CustomFileChooser.this);
parent.repaint();
}
#Override
public void cancelSelection(){
super.cancelSelection();
//Perform cancel action here
System.out.println("Canceled");
parent.remove(CustomFileChooser.this);
parent.repaint();
}
#Override
public void show(){
rescanCurrentDirectory();
parent.add(this);
revalidate();
repaint();
}
#Override
public Dimension getMaximumSize(){
//Not necessary - But I felt the chooser should have a maximum size
return new Dimension(500,300);
}
}
}
FullscreenLib
//import
import argha.util.Fullscreen;
//this for JFrame
//true for setting Undecorated on/off
Fullscreen screen = new Fullscreen(this, true);
screen.DoTheWorkFor();
You can use my library for creating fullscreen windows and the problem you are facing hope it solved after that i tested and its working.
Hope it may helped you

Java Swing - Text and buttons not showing up

Trying everything, just not showing up:
package me.ultimate.ST;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
public class ST extends JFrame {
private static final long serialVersionUID = 1L;
public ST() {
setSize(500, 600);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setUndecorated(true);
getContentPane().setBackground(Color.BLACK);
JLabel label = new JLabel("Test");
label.setText("Some Test!");
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
ST ex = new ST();
ex.setVisible(true);
}
});
}
}
I then just get a black box.
You need to add the label to the frame:
label.setText("Some Test!");
add(label);
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.
You forgot to add the label to the frame :)
add(label, BorderLayout.CENTER);
Whatever layout you wish to use...

How to run/compile Java code from JTextArea at Runtime?

I have a JInternalFrame painted with a BufferedImage and contained in the JDesktopPane of a JFrame. I also have a JTextArea where I want to write some java code (function) that takes the current JInternalFrame's painted BufferedImage as an input and after doing some manipulation on this input it returns another manipulated BufferedImage that paints the JInternalFrame with new manipulated Image again.
Manipulation java code of JTextArea:-
public BufferedImage customOperation(BufferedImage CurrentInputImg)
{
Color colOld;
Color colNew;
BufferedImage manipulated=new BufferedImage(CurrentInputImg.getWidth(),CurrentInputImg.getHeight(),BufferedImage.TYPE_INT_ARGB);
// make all Red pixels of current image black
for(int i=0;i< CurrentInputImg.getWidth();i++) {
for(int j=0;j< CurrentInputImg.getHeight(),j++) {
colOld=new Color(CurrentInputImg.getRGB(i,j));
colNew=new Color(0,colOld.getGreen(),colOld.getBlue(),colOld.getAlpha());
manipulated.setRGB(i,j,colNew.getRGB());
}
}
return manipulated;
}
How can I run/compile this JTextArea java code at runtime and get a new
manipulated image for painting on JInternalFrame?
Here is my Main class:
(This class is not actual one but I have created it for you for basic interfacing containing JTextArea,JInternalFrame,Apply Button)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.JInternalFrame;
import javax.swing.JDesktopPane;
import java.awt.image.*;
import javax.imageio.*;
import java.io.*;
import java.io.File;
import java.util.*;
class MyCustomOperationSystem extends JFrame
{
public JInternalFrame ImageFrame;
public BufferedImage CurrenFrameImage;
public MyCustomOperationSystem() {
setTitle("My Custom Image Operations");
setSize((int)Toolkit.getDefaultToolkit().getScreenSize().getWidth(), (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight());
JDesktopPane desktop=new JDesktopPane();
desktop.setPreferredSize(new Dimension((int)Toolkit.getDefaultToolkit().getScreenSize().getWidth(),(int)Toolkit.getDefaultToolkit().getScreenSize().getHeight()));
try {
CurrenFrameImage=ImageIO.read(new File("c:/Lokesh.png"));
}catch(Exception exp) {
System.out.println("Error in Loading Image");
}
ImageFrame=new JInternalFrame("Image Frame",true,true,false,true);
ImageFrame.setMinimumSize(new Dimension(CurrenFrameImage.getWidth()+10,CurrenFrameImage.getHeight()+10));
ImageFrame.getContentPane().add(CreateImagePanel());
ImageFrame.setLayer(1);
ImageFrame.setLocation(100,100);
ImageFrame.setVisible(true);
desktop.setOpaque(true);
desktop.setBackground(Color.darkGray);
desktop.add(ImageFrame);
this.getContentPane().setLayout(new BorderLayout());
this.getContentPane().add("Center",desktop);
this.getContentPane().add("South",ControlPanel());
pack();
setVisible(true);
}
public JPanel CreateImagePanel() {
JPanel tempPanel=new JPanel() {
public void paintComponent(Graphics g) {
g.drawImage(CurrenFrameImage,0,0,this);
}
};
tempPanel.setPreferredSize(new Dimension(CurrenFrameImage.getWidth(),CurrenFrameImage.getHeight()));
return tempPanel;
}
public JPanel ControlPanel() {
JPanel controlPan=new JPanel(new FlowLayout(FlowLayout.LEFT));
JButton customOP=new JButton("Custom Operation");
customOP.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evnt) {
JFrame CodeFrame=new JFrame("Write your Code Here");
JTextArea codeArea=new JTextArea("Your Java Code Here",100,70);
JScrollPane codeScrollPan=new JScrollPane(codeArea,ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
CodeFrame.add(codeScrollPan);
CodeFrame.setVisible(true);
}
});
JButton Apply=new JButton("Apply Code");
Apply.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event){
// What should I do!!! Here!!!!!!!!!!!!!!!
}
});
controlPan.add(customOP);
controlPan.add(Apply);
return controlPan;
}
public static void main(String s[]) {
new MyCustomOperationSystem();
}
}
Note: in the above class JInternalFrame (ImageFrame) is not visible even though I have declared it visible. So, ImageFrame is not visible while compiling and running the above class. You have to identify this problem before running it.
Take a look at the Java 6 Compiler API
If you want to actually compile code from within java, it's doable but not trivial.
It's much better to use a scripting framework like Groovy--that would work great. Groovy is very java-compatible, it will almost always run java code directly (there are a few strange exceptions)
BeanShell is another scripting framework.
These both do just what you want without the effort of trying to figure out how to compile a class then load it into your existing runtime. (Actually, the problem I've seen isn't the initial compile, it's flushing your class so you can replace it with a new one after an edit).

Categories

Resources