How to get the Java Output screen? - java

I am trying to display images on the screen using Graphics but the screen doesn't load
The output screen appears but only show The black screen and not the images
The code gets compiled properly so why am i not getting the output
package game;
import java.awt.*;
import javax.swing.JFrame;
public class Screen {
private GraphicsDevice vc;
public Screen(){
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
vc=env.getDefaultScreenDevice();
}
public void setFullScreen(DisplayMode dm, JFrame window){
window.setUndecorated(true);
window.setResizable(false);
vc.setFullScreenWindow(window);
if(dm !=null && vc.isDisplayChangeSupported()){
try{
vc.setDisplayMode(dm);
}catch(Exception ex){}
}
}
public Window getFullSCreenWindow(){
return vc.getFullScreenWindow();
}
public void resotreScreen(){
Window w= vc.getFullScreenWindow();
if(w!=null){
w.dispose();
}
vc.setFullScreenWindow(null );
}
}
package game;
import java.awt.*;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
class Images extends JFrame{
public static void main(String[] args){
DisplayMode dm = new DisplayMode(800,600,16,DisplayMode.REFRESH_RATE_UNKNOWN);
Images i = new Images();
i.run(dm);
}
private Screen s;
private Image bg;
private Image pic;
private boolean loaded;
public void run(DisplayMode dm){
setBackground(Color.BLUE);
setForeground(Color.WHITE);
setFont(new Font("Arial",Font.PLAIN,24));
loaded =false;
s = new Screen();
try{
s.setFullScreen(dm, this);
loadpics();
try{
Thread.sleep(10000);
}catch(Exception ex){}
}finally{
s.resotreScreen();
}
}
public void loadpics(){
bg = new ImageIcon("C:\\Users\\Dhruv\\Downloads\\Ronaldo.jpg").getImage();
pic =new ImageIcon("C:\\Users\\Dhruv\\Downloads\\Messi.jpg").getImage();
loaded= true;
repaint();
}
public void paint(Graphics g){
if(g instanceof Graphics2D){
Graphics2D g2 =(Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
}
if(loaded){
g.drawImage(bg,0,0,null);
g.drawImage(pic,170,180,null);
}
}
}

Let's start with background information...
A JFrame is a container for a JRootPane, which contains the contentPane, JMenuBar and JGlassPane
When you override paint of top level container like JFrame, you are only painting the bottom most component, the JRootPane and it's contents are then painted over the top, making it kind of pointless.
See How to Use Root Panes for more details
Painting is also a complex operation, failing to call super.paint will cause no end of issues, make sure you always call the super paint method before painting unless you really understand how it works and are prepared to do it's job manually.
In Swing you are instead encouraged to extend from a JComponent based class (JPanel been the preferred) and override its paintComponent method and perform your custom paint there
This component can either be added to the window or set as the contentPane or added to some other container depending on your needs.
See Painting in AWT and Swing and Performing Custom Painting for more details.
ImageIcon uses background thread to load it's images, so even though it returns, the image might not be realised (or fully loaded). When you use g.drawImage(bg,0,0,null);, passing null as the ImageObserver, it prevents the container from knowing when the image changes and allowing it to automatically repaint itself.
What's cool is, all Component based classes implement ImageObserver, so pretty much anything which can paint can act as an ImageObserver.
Convention would encourage to pass this as the ImageObserver.
Generally, a better solution is to use ImageIO, which when it loads images, won't return until the image is fully realised.
Have a look at Reading/Loading an Image for more details.
Thread.sleep(10000); is a dangerous thing to use in Swing. It has the potential to stop the UI from been updated or respond to other input and events, making your program appear as if it's hung, because it has. But in your case, it means you're violating the single thread rules of Swing.
Swing is a single threaded environment, you should never perform any action which might block the Event Dispatching Thread and you should never update the UI from outside the context of the EDT.
There are solutions available to help you, Swing Timer for generating periodical events which are dispatched within the EDT and SwingWorker for performing long running operations which have support for updating the UI.
See The Event Dispatch Thread for more details.
My recommendation is to not worry about the full screen support, focus on getting the images painting using a normal window and the add the full screen support. This allows you to solve problems within an isolated set of functionality, making it much easier to solve.

Related

how to call a graphical method in actionperformed?

I am kinda new to java and would like to invoke a graphical method in ActionEvent, for instance let's say I would like a square to be drawn when button b is pressed? Will appreciate any help thanks:
package Mst;
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
public class Cours2_2 extends Applet implements ActionListener {
Button a,b,c;
public void init(){
setBackground(Color.pink);
a= new Button("KIRMIZI");
a.addActionListener(this);
add(a);
b= new Button("BEYAZ");
b.addActionListener(this);
add(b);
c= new Button("SARI");
c.addActionListener(this);
add(c);
}
public void paint(Graphics g){
g.drawString("s", 5, 5);
}
public void actionPerformed(ActionEvent e){
String s= e.getActionCommand();
if(s.equals("KIRMIZI")){
setBackground(Color.red);
}
if(s.equals("BEYAZ")){
setBackground(Color.white);
}
if(s.equals("SARI")){
setBackground(Color.yellow);
}
drawStrings(t);
}
public void drawStrings(Graphics t) {
t.setColor(Color.yellow);
t.fillRect(0, 0, 75 ,75);
}
}
I would like to know if I should create this square which I want drawn when a button is pressed as a method or a function. Thanks
Avoid Applet, if you "really" have to, use JApplet instead. Having said that, you should start with JPanel and override it's paintComponent method instead (and make sure you call super.paintComponent before doing any custom painting. Take a look at Painting in AWT and Swing and Performing Custom Painting for more details.
Generally speaking, painting in AWT/Swing is passive, that is, when the system "decides" something needs to be updated, it will then be painted. This means that you (generally) have little control over when something will be painted. You make suggestions, but it's update to the system to decide what and when something is painted.
You paint methods should paint the current state of the component. This means that you will need to provide some information and logic that the paint methods can use to make decisions about what to paint. For example, you could have a flag, which is changed by the ActionListener, which calls repaint on your component and when the component is painted, you would test the state of this flag and make decisions on what should be done (like drawing a square for example).
A more complicated approach might use a List and take advantage of the Shape API, adding or removing shapes to the List which the paint method would then be able to iterate over and paint
Have a look at Collections Trail and
2D Graphics for more details

Why isn't my JFrame repainting like I told it to?

When instantiating my modified JPanel class, I pass in a file through the constructor. The file (XML) gets read and the data gets used by me later in the paint method. However, right after I parse the data, I call both repaint() and revalidate(), but my GUI looks exactly the same. I call these methods both in my main class which extends JFrame and my panel class which extends JPanel.
When I choose an xml file from my JFileChooser, the drawPanel class gets instantiated with its other constructor, taking in the file and parsing it, then calling repaint and revalidate. I omitted most of the code to save your time.
Here's the main class' code:
public class myCode extends JFrame {
public myCode() {
super("Roadway Simulator");
setSize(800, 600);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(null);
drawie = new drawPanel();
drawie.setSize(new Dimension(width - 200, height));
drawie.setMinimumSize(new Dimension(width - 200, height));
drawie.setMaximumSize(new Dimension(width - 200, height));
drawie.setLocation(0, 0);
add(drawie);
setVisible(true);
try{Thread.sleep(500);revalidate();repaint();}catch(InterruptedException eeee){}
}
public static void main(String[] args){new myCode();}
}
Here's my drawPanel class:
class drawPanel extends JPanel {
boolean drawRoad = false;
public drawPanel() {
super();
}
public drawPanel(Document doc){
super();
//the change in my paint method
drawRoad = true;
revalidate();
repaint();
}
public paint(Graphics g){
super.paint(g);
if(drawRoad){
g.setColor(Color.BLACK);
g.fillRect(0,0,600,600);
}
}
}
My code is the same as above, just with a lot more detail. Why isn't my JFrame repainting?
Here:
try{Thread.sleep(500);revalidate();repaint();}catch(InterruptedException eeee){}
Understand what Thread.sleep(...) does to a Swing GUI when called on the Swing event thread -- it puts the current thread which happens to be the Swing event thread, the one responsible for all drawing and user interaction, to sleep. In other words, you put your entire application completely to sleep.
Solution -- don't call this ever on the event thread.
As an aside, there's no cost to putting each method call on its own line, and no reason for that long line that you've posted as it serves no purpose other than to confuse.
try{Thread.sleep(500);revalidate();repaint();}catch(InterruptedException eeee){} is most likely blocking the Event Dispatching Thread, preventing from processing the Event Queue and making it look like your program has hung.
See Concurrency in Swing for more details...
It is also not recommended to override paint of Swing components and instead use paintComponent, see Performing Custom Painting for more details
In your case, I would recommend using a javax.swing.Timer instead of Thread.sleep, see How to use Swing Timers for more details
Updated
I don't see any where in your code that would change drawRoad from false to true, so your paint method is painting...nothing...so I guess you frame is painting exactly the way you told it to...
You may also like to take a look at Initial Threads and you might like to have a read through Code Conventions for the Java TM Programming Language, it will make it easier for people to read your code and for you to read others
Updated
Given that you example is incomplete and won't compile, when I rebuild it, this will work...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import org.w3c.dom.Document;
public class TestDraw extends JFrame {
public TestDraw() {
super("Roadway Simulator");
setSize(800, 600);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DrawPanel drawie = new DrawPanel(null);
add(drawie);
setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
new TestDraw();
}
});
}
class DrawPanel extends JPanel {
boolean drawRoad = false;
public DrawPanel() {
super();
}
public DrawPanel(Document doc) {
super();
drawRoad = true;
revalidate();
repaint();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(600, 600);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (drawRoad) {
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
}
}
}
}
If I change DrawPanel drawie = new DrawPanel(null); to DrawPanel drawie = new DrawPanel(); it still paints, but doesn't perform your custom painting.
The other problem is, as has already been highlighted, is the use of null layouts
Avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify.
Have a look at Why is it frowned upon to use a null layout in SWING? for more details...
Now, having said that, when you add drawie, you never give it a size, Swing is smart enough not to paint 0x0 sized components...

Using java bufferstrategy and swing elements at the same time

I program a simple RTS game now, and it is my first experience in game design. My problem is that when I use createBufferStrategy(2) all swing elements (buttons etc...) not displayed after bufferStrategy.show(); method is invoked. My game is full of buttons, tables and other crap, and I really don't want to code all this by my own. Also I really like Java's layouts, and want to make all GUI on this.
So, here is little code example, not from my game, but it is a good demonstration of my problem. Thanks.
Btw, I understand the source of my problem. I know that swing draw mechanic is event-based, while using bufferstrategy is not event-based. But I don't know how to solve this. Thank you.
And final - I don't want to use default swing event-based approach becouse it is slow for games, and as far as I know the bufferstratgey is only approach for games. Thx.
public static void main(String[] args){
final JFrame frame = new JFrame();
JPanel menuPanel = new JPanel();
final Button button = new Button("Exit");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
menuPanel.add(button);
frame.add(menuPanel);
frame.setPreferredSize(new DimensionUIResource(800, 600));
//frame.setResizable(false);
//frame.setUndecorated(true);
//frame.setIgnoreRepaint(true);
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
final long delay = 1000/60;
frame.pack();
frame.setVisible(true);
final GraphicsDevice device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
if (device.isFullScreenSupported()){
device.setFullScreenWindow(frame);
// this place. If I turn into fullscreen mode button disappear. And if I stay in windowed mode button exist and work;
}
frame.createBufferStrategy(2);
final BufferStrategy bufferStrategy = frame.getBufferStrategy();
Thread renderingThread = new Thread(){
public void run(){
while (true){
long startRenderingTime = System.currentTimeMillis();
Graphics g = bufferStrategy.getDrawGraphics();
g.setColor(Color.white);
g.fillRect(0,0,1680,1050);
//button.paint(g);
//button.paintAll(g);
// I don't know how to draw button!
g.dispose();
if (!bufferStrategy.contentsLost()){
bufferStrategy.show();
}
long endRenderingTime = System.currentTimeMillis();
long actionTime = endRenderingTime-startRenderingTime;
try {
if (actionTime>delay){
sleep(5);
} else {
sleep(delay-actionTime);
}
} catch (InterruptedException e){
return;
}
}
}
};
renderingThread.start();
}
});
}
You're running an infinite loop on Swings EDT, effectively blocking Swing from doing anything.
I don't see for what you even need BufferStrategy when you want to display Swing elements. To combine custom rendering with Swing components you normally just create a component that renders your stuff and add it to the normal layout.
Your component just overwrites paintComponent() and draws whatever it needs to. You can easily trigger an update of your component by calling repaint() on it. This performs usually well enough. Note that Swing components are double buffered by default, so there is no need to work with BufferStrategy there.
If you want to stick to active rendering, you could call Swings rendering chain selectively, for example you could get the Frame's ContentPane and just call paint() in your rendering loop. But hacking it this way may cause unwanted side effects.

Repaint not validating?

Hello everyone I am quite new to applets in java and was wondering why my oval was not moving up the screen when I press the up key. I said repaint in the paint method and nothing is happening
Any Ideas? (Please don't be rude I am new to applets so...)
package mypackage;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.applet.*;
public class gameapplet extends Applet {
int charecterx = 500;
int charectery = 250;
public void init(){
addKeyListener(new AL());
setSize(1000,1000);
setBackground(Color.RED);
}
public void paint(Graphics g){
//Paint Method
g.setColor(Color.BLACK);
g.fillOval(charecterx,charectery,100,100);
repaint();
}
public class AL extends KeyAdapter
{
public void keyPressed (KeyEvent e)
{
int keyCode = e.getKeyCode();
//If Statements To see if user is moving
if(keyCode == e.VK_UP)
{
if(charecterx <= 0)
{
charecterx = 0;
}
else
{
charecterx--;
}
}
}
public void keyRealesed(KeyEvent e){
}
}
}
You're main problem comes down to two main issues...
1- You are using a KeyListener
KeyListeners are notorious for being problematic in that they only respond to keystrokes when the component they are registered to are focusable AND have focus.
2- You never call repaint from within the keyPressed method to request that the applet be repainted.
You should avoid Applet as it is woefully out of date and generally not used by many people anymore. Instead use JApplet, in fact, I would recommend avoiding applets altogether until you understand the API better
Don't call setSize on an applet, the size of applet is defined by the html tag it is created from.
Don't call repaint or anything that might call repaint from within any paint method
Don't override paint, it's too easy to break the paint chain (which you have) and for top level containers like Applet, isn't double buffered. In fact AWT generally isn't double buffered, which will cause flickering when the component is repainted. Instead, you should use something like a JPanel and override it's paintComponent method
Don't use KeyListener, it has too many issues with focus. Instead, make use of the Key Bindings API which provides you with more control and a much more reusable API
Take a look at:
Creating a GUI With JFC/Swing
Performing Custom Painting
Painting in AWT and Swing
For more details
It depends on the version of your jdk.
In jdk1.6 I would use this
invalidate();
validate();
repaint();
In jdk 1.7 I would use
revalidate();
repaint();

Java: Paint Method Doesn't Run

I've looked at several other posts, and I have yet to find a clear answer. I don't entirely understand the paint method, which is probably my problem, but nowhere can I find a clear explanation. Can someone help me get this one working? The issue is that the paint method is not running. Everything else seems to work fine, but I do not see the oval I tell the program to render in the frame.
import java.awt.Color;
import java.awt.Component;
import java.awt.Frame;
import java.awt.Graphics;
#SuppressWarnings("serial")
public class TestObject extends Component {
MouseResponder mouseListener = new MouseResponder(); // Creates a new mouse listener.
WindowResponder windowListener = new WindowResponder(); // Creates a new window listener.
Frame mainFrame = new Frame(); // Makes a new frame.
public TestObject() {
mainFrame.setSize(400,500); // Makes the new frame 400 by 500 in size.
mainFrame.setLocationRelativeTo(null); // Sets the location of the window to center it.
mainFrame.setTitle("A Test program!"); // Sets frame label.
mainFrame.setBackground(new Color(199,199,199)); // Sets the background color of the window.
mainFrame.addWindowListener(windowListener); // Adds the window listener so close works.
mainFrame.addMouseListener(mouseListener); // Adds the mouse listener to the frame.
mainFrame.setVisible(true); // Makes the new frame visible.
System.out.println("[TestObject] Window" + // Prints a console message when main window is launched.
" configured and launched.");
}
public void paint(Graphics pane) {
System.out.println("[TestObject] Painting.");
pane.setColor(Color.BLACK);
pane.drawOval(10,10,10,10);
}
}
Other Info:
MouseResponder and WindowResponder are separate functioning classes.
The TestObject class seen above is called by a main class which
creates a new TestObject. The frame displays successfully as I
specify.
Thank you for any help!
-Docithe
You are late for your homework buddy !
Take a new java file.
Create a class
Make it extend JFrame
override the paint method
put a println in it
Take a second file
put a main in it
instanciate your first class and call show
move the window around, println should print out, meaning your code in paint is executing.
That's the way to do it in OOP, and for sure in java. Read more.
paint() is responsible for rendering a component when it is visible.
At least in your code snippet, you did not add the test-component to the frame - thus, it is not displayed and not painted.
public TestObject() {
//...
mainFrame.add( this );
//...
}
This still might not work because your Test Component is 0x0 pixel.
So you also
#Override
getPreferredSize(){
return new Dimension( 20, 20 );
}
you are mixing two things here, creating a frame and creating a component. If I understand you correctly, you want to create a frame and within that frame have a custom component draw an oval.
The component is just this:
public class TestObject extends Component {
public void paint(Graphics pane) {
System.out.println("[TestObject] Painting.");
pane.setColor(Color.BLACK);
pane.drawOval(10,10,10,10);
}
}
and your main program looks more like this:
public static void main(String[] args)
{
MouseResponder mouseListener = new MouseResponder();
WindowResponder windowListener = new WindowResponder();
Frame mainFrame = new Frame();
mainFrame.setSize(400,500);
mainFrame.setLocationRelativeTo(null);
mainFrame.setTitle("A Test program!");
mainFrame.setBackground(new Color(199,199,199));
mainFrame.addWindowListener(windowListener);
mainFrame.addMouseListener(mouseListener);
mainFrame.add(new TestObject());
mainFrame.setVisible(true);
}
I am not saying this code will run, but it splits the two things in what they should be, a main program creating the frame, and a component painting an oval. I agree with Snicolas on the reading more...

Categories

Resources