Why wil this not run.
Jframe isnt an option what can i use, and how come i have to have
graphics g as a component? as well as how is Graphics g set up as a parameter ?
class Tables{
public staic void main (String [] args){
Button mainscreen = new Button(Graphics g);
g.drawRect(10, 10, 50, 50);
}
}
will this work
No.
Read the section from the Swing tutorial on Custom Painting for working examples of how to do painting.
And yes you need a window of some kind (JFrame or JDialog) to display the panel.
If you don't want the borders then you can use an undecorated frame.
JFrame frame = new JFrame();
frame.setUndecorated(true);
Related
I have been experimenting with drawing on a JFrame, so I could use these experiments in the future for a program I might create. However, I have found a problem that I am not able to solve:
How to draw stuff while having a timer set up.
public static void MyTimer() {
JFrame frame = new JFrame("Colors");
int width = 700;
int height = 700;
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setBackground(Color.BLACK);
frame.pack();
frame.setSize(width, height);
frame.setVisible(true);
frame.setResizable(false);
TimerTask task;
task = new TimerTask() {
int a = 2;
#Override
public void run(Graphics g) {
g.drawRect(a, 2, a + 66, 68);
g.fillRect(a, 2, a + 66, 68);
a = a + 20;
}
};
timer.schedule(task, 0, 1000);
}
As you can see, I am trying to draw a new square every second. The problem is, I get an error in the code:
method does not override or implement a method from a supertype
How can I fix this?
How can I fix this?
The run() method does not take a parameter. Get rid of the Graphics parameter. That will get rid of the compile error.
However, that still will not help with your painting.
Instead you need to override the paintComponent(...) method of a JPanel then you add the panel to the frame. Then you use the Graphics object passed to the paintComponent() method to do your painting.
Read the section from the Swing tutorial on Custom Painting for more information and working examples to get you started.
Also you should NOT be using a TimerTask for animation. You should be using a Swing Timer. Then in the actionPerformed(...) method of the ActionListener you would change the properties of your custom painting (ie in your case add a new square object to be painted) and then invoke repaint() on the panel.
, I am trying to draw a new square every second
Check out the DrawOnImage example found in Custom Painting Approaches. It will show you how to add a Rectangle object to a BufferedImage.
I managed to fix it but I don't understand why the same code results in different results. Some classmates have had the same problem.
The issue is that it I use miVentana.setVisible(true); before chicha(); the elements inside the JPanel will show when executing but if I run it again sometimes they won't ve visible until I resize the window, a few times not even the JPanel background color was visible. Just clicking the "Run" bottom on the IDE without changing anything else.
I just tried it 10 consecutive times and the elements were only visible on the 4th attempt.
Could this come from some memory garbage remaining from previous executions of the code?
I'm using Eclipse Version: Photon Release (4.8.0).
This is the code with the weird behaviour:
public class Ej10 extends JFrame {
public Ej10() {
setLayout(null);
}
static Ej10 miVentana = new Ej10();
public static void main(String[] args) {
miVentana.setTitle("Ejercicio10");
miVentana.setBounds(20, 20, 500, 600);
miVentana.setLocationRelativeTo(null);
miVentana.setVisible(true);
chicha();
//miVentana.setVisible(true);
}
static void chicha() {
JPanel miPanel = new JPanel();
miPanel.setLayout(new BoxLayout(miPanel, BoxLayout.PAGE_AXIS));
miPanel.setBounds(20, 20, 350, 450);
miPanel.setBackground(Color.CYAN);
JLabel lUsuario = new JLabel("Usuario:");
lUsuario.setVisible(true);
JTextField campoUsuario = new JTextField();
JLabel lPwd = new JLabel("ContraseƱa:");
JPasswordField campoPwd = new JPasswordField();
JButton bAcceso = new JButton("Acceder");
miPanel.add(lUsuario);
miPanel.add(campoUsuario);
miPanel.add(lPwd);
miPanel.add(campoPwd);
miPanel.add(bAcceso);
miPanel.setVisible(true);
miVentana.add(miPanel);
}
}
Components need to be added to the frame BEFORE the frame is made visible.
One of the functions of the setVisible() method is to invoke the layout manager. Otherwise components have a size() of (0, 0) so there is nothing to paint.
Also, all GUI components should be created on the Event Dispatch Thread (EDT), otherwise you can have random results. Read the section from the Swing tutorial on Concurrency for more information.
Take a look at the FrameDemo from How to Make Frames for the most basic example of how your code should be structured to avoid problems. It shows how to create components on the EDT and how to make the frame visible.
they won't ve visible until I resize the window,
Resizing the frame will also cause the layout manager to be invoked.
miPanel.setBounds(20, 20, 350, 450);
That statement will do nothing because the layout manager of the frame will determine the size and location of the panel based on the rules of the layout manager. The default layout manager for a frame is a BorderLayout, so basically the panel will get all the space available to the frame.
The tutorial also has a section on Layout Managers that you should read.
I have a JFrame with a JLabel on top called "coloredLabel", an instance of the class it's in is running on both of them. a random amount of objects move around on the frame and label and don't directly interact with them.
The only problem is that there is a bit of the frame visable above the label, what I want is that the label fully alligns with the frame, without pasting over the objects (which are painted in with an override paint method and mentioned as "game.newBall" and "game.moveBall". "test" is the name of the class.
Here is how my main thread looks, the frame and the label are declared within it:
public static void main(String[] args) throws InterruptedException {
JFrame frame = new JFrame("Bounce 2.0");
JLabel coloredLabel = new JLabel("");
test game = new test();
frame.add(game);
frame.setSize(300, 400);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
coloredLabel.setOpaque(true);
coloredLabel.setBackground(game.backgroundColor);
coloredLabel.setPreferredSize(new Dimension(1000000,1000000));
frame.getContentPane().add(coloredLabel,BorderLayout.LINE_START);
game.add(coloredLabel);
for(int a = randInt(0,9); a<10; a++)
game.newBall(randInt(0,300),randInt(0,400));
while (true) {
double height = frame.getContentPane().getSize().getHeight();
double width = frame.getContentPane().getSize().getWidth();
int n = 0;
while(game.exists(n)==true){
game.moveBall(n,width,height);
n++;
}
game.repaint();
Thread.sleep(10);
}
}
So my question is:
How do I allign the JLabel with the JFrame? so there is no space in between the JLabel and the frame.
I searched for this on this site, but couldn't find the same problem or something similar enough so I could fix this.
solved - game.setBackground(...);
The only problem is that there is a bit of the frame visable above the label,
game.add(coloredLabel);
I'm guessing "game" is a JPanel. By default a JPanel uses a FlowLayout and by default the FlowLayout has horizontal and vertical gaps of 5 pixels.
Get rid of the gap in the FlowLayout. Read the API for the constructors/methods of the FlowLayout to customize its behaviour.
But of course the bigger issue is the design of your app. I don't understand your point of using the label and attempting to take up all the space of the frame. Just set the background of the game panel by using:
game.setBackground(...);
Also class names should:
start with an upper case character and
be descriptive.
"test" is neither.
Alright so I've got this JFrame with a screen on it. I've set the size to 800 by 800. However the window is created smaller than that. It's not a problem with the taskbar because it's not fullsize.
package sharph;
import java.awt.Dimension;
import javax.swing.JFrame;
public class Main extends JFrame {
public static String Title = "Game 1";
public static Dimension screenSize = new Dimension(800,800);
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setTitle(Title);
frame.setSize(screenSize);
frame.setLocationRelativeTo(null);
frame.setResizable(true);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
Screen screen = new Screen();
screen.setSize(screenSize);
frame.add(screen);
frame.setVisible(true);
}
}
In the screen class the paint method draws a box around where the border should be:
//Draw border
g.setColor(Color.RED);
g.drawRect(1, 1, 799, 799);
When I run it, the window is smaller than the box and the bottom and right sides are cut off.
Note the second picture I manually re-sized to show the border difference.
I realize that I have drawn the box 1 pixel smaller on each side, but the difference is much more than 2 pixels.
This happens because the content needs to squeezed into the size of the frame minus its borders.
Checkout this question and this question for a more detailed explanation
The layout manager is also overriding the size property you set on the Screen component. In either case, you should be overriding the getPreferredSize method of the Screen class
Also, you shouldn't be relying on magic numbers or assumptions about the actual size of the component, but should, instead, be using getWidth and getHeight instead (I know, it's just for demonstration purposes)
Instead of "screen.setSize(screenSize);" type "screen.setPreferredSize(screenSize);" and then after you type "frame.setVisible(true);" type "frame.pack()". You can also remove "frame.setSize(screenSize);" if you want to.
Simply stated, I am trying to make a game I am working on full-screen.
I have the following code I am trying to use:
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gs = ge.getDefaultScreenDevice();
if(!gs.isFullScreenSupported()) {
System.out.println("full-screen not supported");
}
Frame frame = new Frame(gs.getDefaultConfiguration());
Window win = new Window(frame);
try {
// Enter full-screen mode
gs.setFullScreenWindow(win);
win.validate();
}
Problem with this is that I am working within a class that extends JPanel, and while I have a variable of type Frame, I have none of type Window within the class.
My understanding of JPanel is that it is a Window of sorts, but I cannot pass 'this' into gs.setFullScreenWindow(Window win)... How should I go about doing this?
Is there any easy way of calling that, or a similar method, using a JPanel?
Is there a way I can get something of type Window from my JPanel?
-
EDIT: The following method changes the state of JFrame and is called every 10ms:
public void paintScreen()
{
Graphics g;
try{
g = this.getGraphics(); //get Panel's graphic context
if(g == null)
{
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setExtendedState(frame.getExtendedState()|JFrame.MAXIMIZED_BOTH);
frame.add(this);
frame.pack();
frame.setResizable(false);
frame.setTitle("Game Window");
frame.setVisible(true);
}
if((g != null) && (dbImage != null))
{
g.drawImage(dbImage, 0, 0, null);
}
Toolkit.getDefaultToolkit().sync(); //sync the display on some systems
g.dispose();
}
catch (Exception e)
{
if(blockError)
{
blockError = false;
}
else
{
System.out.println("Graphics context error: " + e);
}
}
}
I anticipate that there may be a few redundancies or unnecessary calls after the if(g==null) statement (all the frame.somethingOrOther()s), any cleanup advice would be appreciated...
Also, the block error is what it seems. I am ignoring an error. The error only occurs once, and this works fine when setup to ignore the first instance of the error... For anyone interested I can post additional info there if anyone wants to see if that block can be removed, but i'm not concerned... I might look into it later.
Have you made any progress on this problem? It might be helpful if you could update your question with your expected behavior and what the code is actually doing? As was already pointed out, JFrame is a subclass of Window, so if you have a JFrame, you don't need a Window.
For what it's worth, I have a Java app which works in fullscreen mode. Although the screen is not repainted as often as yours, it is repainted regularly. I do the following to enter fullscreen:
// pseudo-code; not compilable
JPanel container = new JPanel();
container.setOpaque( true ); // make sure the container will be visible
JFrame frame = new JFrame();
frame.getContentPane().add(container); // add the container to the frame
frame. ... //other initialization stuff, like default close operation, maximize, etc
if ( fullScreenModeIsSupported )
frame.setUndecorated( true ); // remove window decorations from the frame
gs.setFullScreenWindow( frame );
frame.validate();
Then whenever I need to update the screen, I just plug a new JPanel into the container JPanel:
// pseudo-code; not compilable
container.removeAll(); // clean out the container
container.add( jPanelWithNewDisplay ); // add the new display components to the container
container.validate(); // update and redisplay
container.repaint();
Can't claim that it's technically perfect, but it works well for me. If the pseudo-code examples don't cut it, I can spend some time putting together a compilable example.
JPanel is not a subclass of Window. JFrame is.
So you could try:
JFrame yourFrame = new JFrame();
yourFrame.add(yourPanel);
appyYourFullScreenCodeFor( yourFrame );
That should work.
I think I got what you need.
Set the frame undecorated, so it
comes without any title bar and
stuff.
Add your panel to the frame., so it
looks like only your panel is shown.
Maximize your frame. So now it
should look like there's only your
panel taking the full screen without
and window stuff.
frame.setUndecorated(true);
frame.add(panel); //now maximize your
frame.
Note: Its important to note that the undecorated API can only be called when your frame is undisplayable, so if its already show, then first you need to do setVisible(false).
EDIT1: If all you want is to get the window containing your panel, then you can do this:
Window win = SwingUtilities.getAncestorOfClass(Window.class, myPanel);
Once you get the window instance you can pass it wherever you want.
EDIT2: Also the Frame class extends Window so you can directly do gs.setFullScreen(frame). You dont need to create a new window for that frame.
My understanding of JPanel is that it
is a Window of sorts
Why would you think that? Did you read the API? Does JPanel extend from Window?
You can try using the SwingUtilities class. It has a method that returns the Window for a given component.