How do you make a JFrame intangible? - java

Im a real novice at java coding and for just a little project I'd like the following code to be untouchable eg. anything behind the frame(and its contents) can be clicked on. But I don't know how to do it! I've searched everywhere but haven't found anything.
import java.awt.*;
import java.swing.*;
public class swag {
static Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
public static void main(String[] args)throws Exception{
JLabel lb = new JLabel();
lb.setFont(new Font("Century Gothic",Font.PLAIN,50));
lb.setHorizontalAlignment(SwingConstants.CENTER);
lb.setForeground(Color.WHITE);
lb.setBackground(Color.BLACK);
JFrame f = new JFrame();
f.setSize(dim.width,100);
f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
f.setUndecorated(true);
f.add(lb);
f.setVisible(true);
int r=255;int g=0;int b=0;
int a=80;int t=15;
while(true){
while(true){
lb.setText((System.currentTimeMillis()+""));
f.setBackground(new Color(r--,g++,0,a));
Thread.sleep(t);
if(r==0&&g==255){break;}
} while(true){
lb.setText((System.currentTimeMillis()+""));
f.setBackground(new Color(0,g--,b++,a));
Thread.sleep(t);
if(g==0&&b==255){break;}
} while(true){
lb.setText((System.currentTimeMillis()+""));
f.setBackground(new Color(r++,0,b--,a));
Thread.sleep(t);
if(b==0&&r==255){break;}
}}}
}//class
Note: haven't worked on efficiency yet :)

Read about the glass pane of JFrame. Using it you are able to show the UI components but block all user interactions.
Example:
public class FreezePane extends JComponent {
public FreezePane() {
// trap mouse, key, and focus events
addMouseListener( new MouseAdapter() );
addMouseMotionListener( new MouseMotionAdapter() );
addKeyListener( new KeyAdapter() );
addFocusListener( new FocusListener() {
// do not let any component take focus while visible
public void focusLost(FocusEvent e) {
requestFocusInWindow();
}
public void focusGained(FocusEvent e) {}
}
}
}
Then just set the glass pane and make it visible.
JFrame frame = new JFrame();
frame.setGlassPane( new FreePane() );
frame.getGlassPane().setVisible(true);

Related

Why is it not displaying my button?

I am trying to use a layered pane to make a menu for a program I'm working on, but the button won't display. I can't seem to figure out what it is...
public class FlashcardGUI {
public static void main(String[] args)
{
JFrame projectFrame = new JFrame("StudyFast Flashcard");
projectFrame.setName("StudyFast Flashcards");
projectFrame.setSize(1000,600);
projectFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
projectFrame.setVisible(true);
JLayeredPane projectLayeredPane = new JLayeredPane();
projectFrame.setContentPane(projectLayeredPane);
JPanel projectMenu1 = new JPanel();
projectLayeredPane.setLayer(projectMenu1, 0);
final JButton startNow = new JButton();
startNow.setText("Exit");
startNow.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
});
projectFrame.add(projectLayeredPane);
projectLayeredPane.add(projectMenu1);
projectMenu1.add(startNow);
}
}
Put these two lines at the end of your main method. The order is important in order to make the button display.
projectFrame.pack();
projectFrame.setVisible(true);
(Make sure to remove the projectFrame.setVisible(true); you already have on line 9.)
I have updated your code and it is working now. Please see the inline comments for the issue in your code. Hope this helps.
public class FlashcardGUI2 {
public static void main(String[] args) {
JFrame projectFrame = new JFrame("StudyFast Flashcard");
projectFrame.setName("StudyFast Flashcards");
projectFrame.setSize(1000,600);
projectFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
projectFrame.setVisible(true);
JLayeredPane projectLayeredPane = new JLayeredPane();
LayoutManager layout = new FlowLayout(); //creating a FlowLayout object
projectLayeredPane.setLayout(layout); //adding the layout to JLayeredPane
//because JLayeredPane do not have default layout of
//its own. The reason you were not
//getting the button displayed
projectLayeredPane.setPreferredSize(new Dimension(300, 310));
JPanel projectMenu1 = new JPanel();
final JButton startNow = new JButton();
startNow.setText("Exit");
startNow.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
projectLayeredPane.add(projectMenu1,new Integer(50));
projectLayeredPane.add(startNow,new Integer(10));
projectFrame.add(projectLayeredPane);
projectFrame.pack();
}
}

Opening a new JFrame and close previous after clicking button

How can I code a button that, when clicked, closes the current JFrame and opens a new one?
This is what I have so far, but the old frame stays open:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
practise1 s = new practise1();
s.setVisible(true);
}
I have tried using .close() after the first { but it gives me an error.
If you plan on using the originial JFrame later, use setVisible(false) on the original JFrame. If you plan on closing the first JFrame and never reusing it, you can use dispose().
public void actionPerformed(ActionEvent e)
{
if(e.getSource () == button)
{
test = new JFrame();
test.setSize(300,300);
test.setVisible (true);
this.dispose();
}
}
Dispose AFTER creating the new Frame.
Thanks for the help everyone. I got it working using the this.dispose(); method
Lets say current Frame is FirstFrame
and clicking on JButton goes to NewFrame
import javax.swing.*;
public class FirstFrame extends Jframe implements ActionListener{
JButton button;
public FirstFrame(){
setVisible(true);
setSize(500,500);
button=new JButton("Click me");
button.addActionListner(this);
add(button);
}
public static void main(String[] args)
{
new FirstFrame();
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==button)
{
NewFrame nf=new NewFrame(); // Clicking on the Button will OPEN new Frame in NewFrame.java file
dispose(); //this method will close the FirstFrame
}
}
}
you just put this in your code :
(the exemple here i JButton to do this with the ActionPerformed method)
/**********************************************************************/
private void openBTNActionPerformed(java.awt.event.ActionEvent evt) {
dispose();
FrameTarget t = new FrameTaregt();
t.setVisible(true);
//set the size : 1250 pixels de width and 720 pixels de height
t.setSize(1250, 720);
//make the frame in the center wuth this
t.setLocationRelativeTo(null);
t.setResizable(true);
}

MouseEntered and MouseExited not working

I am having trouble with mouseExited and mouseEntered events. They are not executed. And I know it is because of the setLayout. If I comment it, the problem dissapears.This is my code :
public class Test{
public static void main(String[] args) {
new Test();
}
public Test() {
JFrame frame = new JFrame();
frame.setContentPane(new Pane());
frame.getContentPane().setBackground(Color.GRAY);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setUndecorated(true);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public class Pane extends JPanel{
public Pane(){
ImageIcon start = new ImageIcon("Start.png");
JLabel bStart = new JLabel(start);
ImageIcon exit = new ImageIcon("Exit.png");
JLabel bExit = new JLabel(exit);
setLayout(new BorderLayout());
add(bStart, BorderLayout.CENTER);
bStart.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
ImageIcon image = new ImageIcon("Start-Pressed.png");
bStart.setIcon(image);
Container parent = bStart.getParent();
parent.remove(bStart);
add(bExit);
parent.revalidate();
parent.repaint();
}
public void mouseEntered(MouseEvent arg0) {
ImageIcon image = new ImageIcon("Start-Hover.png");
bStart.setIcon(image);
}
public void mouseExited(MouseEvent arg0) {
ImageIcon image = new ImageIcon("Start.png");
bStart.setIcon(image);
}
});
bExit.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
System.exit(0);
}
public void mouseEntered(MouseEvent e){
ImageIcon image = new ImageIcon("Exit-Hover.png");
bExit.setIcon(image);
}
public void mouseExited(MouseEvent e){
ImageIcon image = new ImageIcon("Exit.png");
bExit.setIcon(image);
}
});
}
}
}
And i know it is because of the setLayout. If i comment it, the problem dissapears.
I doubt the layout is the problem. If the component appears, then the layout manager has nothing to do with how MouseEvents are generated.
From you code is looks like you are trying to provide rollover effects. Instead of using a JLabel for this you can use a JButton and set Icons for the different rollover effects:
button.setBorderPainted( false );
button.setRolloverEnabled( true );
button.setRolloverIcon( ... );
button.setRolloverSelectedIcon(...);
button.setSelectedIcon(...);
Then there is no need to manage the MouseListener as the UI will do it for you.
To handle a mousePressed you should then be using an ActionListener on the JButton. Read the section from the Swing tutorial on How to Write an ActionListener for more information.

How can I switch between jpanels?

I'm still very new to java programming, so please help me to correct any mistakes I might have overlooked or give tips on how to improve this program.
Okay, so a lot of problems have been solved, and now I have a CardLayout, but I still have questions about how I should make my pipes show inside it.
When I tried to add in my refresh rate timer and my speed timer, I have problems about how I need to declare and initialize boolean variables.
Also, when I compile and run this game, I get files such as Game$1.class. Is there a way for me to clean this up, and could someone explain why this happens? Do these have an affect on the finished product? (When the game is compiled and packaged into a JAR.)
I want to set playerIsReady to true when the play button is clicked. And from there, when the if statement is true, then switch to a panel that displays the pipes, and start moving the pipe across the screen. Preferably 3 instances of that pipe, each starting at different times, but whatever you can help with is fine.
Some of this code needs work, so I have commented some parts out and left notes.
My other questions about this game can be found here.
This is my current code
Game.java
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;
import javax.swing.SwingUtilities;
public class Game {
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
// the GUI as seen by the user (without frame)
final CardLayout cl = new CardLayout();
final JPanel gui = new JPanel(cl);
// remove if no border is needed
gui.setBorder(new EmptyBorder(10,10,10,10));
JPanel menu = new JPanel(new GridBagLayout());
JButton playGame = new JButton("Play!");
ActionListener playGameListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
cl.show(gui, "game");
}
};
playGame.addActionListener(playGameListener);
Insets margin = new Insets(20, 50, 20, 50);
playGame.setMargin(margin);
menu.add(playGame);
gui.add(menu);
cl.addLayoutComponent(menu, "menu");
final JPanel pipes = new Pipes();
gui.add(pipes);
cl.addLayoutComponent(pipes, "game");
JFrame f = new JFrame("Pipes Game");
f.add(gui);
// Ensures JVM closes after frame(s) closed and
// all non-daemon threads are finished
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// See https://stackoverflow.com/a/7143398/418556 for demo.
f.setLocationByPlatform(true);
// ensures the frame is the minimum size it needs to be
// in order display the components within it
f.pack();
// should be done last, to avoid flickering, moving,
// resizing artifacts.
f.setVisible(true);
/*if (playerIsReady) {
Timer speed = new Timer(10, new ActionListener() { //pipe speed
#Override
public void actionPerformed(ActionEvent e) {
pipes.move();
}
});
speed.start();
Timer refresh = new Timer(30, new ActionListener() { //refresh rate
#Override
public void actionPerformed(ActionEvent e) {
pipes.repaint();
}
});
refresh.start();
}*/
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency
SwingUtilities.invokeLater(r);
}
}
Pipes.java
// What import(s) do I need for ArrayList?
public class Pipes {
List<Pipe> pipes = new ArrayList<Pipe>();
public Pipes() {
pipes.add(new Pipe(50, 100));
pipes.add(new Pipe(150, 100));
pipes.add(new Pipe(250, 100));
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for ( Pipe pipe : pipes ){
pipe.drawPipe(g);
}
}
}
PipeObject.java
import java.awt.Graphics;
public class PipeObject {
//Declare and initialiaze variables
int x1 = 754; //xVal start
int x2 = 75; //pipe width
//total width is 83
int y1 = -1; //yVal start
int y2 = setHeightVal(); //pipe height
int gap = 130; //gap height
public void drawPipe(Graphics g) {
g.clearRect(0,0,750,500); //Clear screen
g.drawRect(x1,y1,x2,y2); //Draw part 1
g.drawRect(x1-3,y2-1,x2+6,25); //Draw part 2
g.drawRect(x1-3,y2+25+gap,x2+6,25); //Draw part 3
g.drawRect(x1,y2+25+gap+25,x2,500-y2-49-gap); //Draw part 4
}
public void move() {
x1--;
}
public int getMyX() { //To determine where the pipe is horizontally
return x1-3;
}
public int getMyY() { //To determine where the pipe is vertically
return y2+25;
}
public int setHeightVal() { //Get a random number and select a preset height
int num = (int)(9*Math.random() + 1);
int val = 0;
if (num == 9)
{
val = 295;
}
else if (num == 8)
{
val = 246;
}
else if (num == 7)
{
val = 216;
}
else if (num == 6)
{
val = 185;
}
else if (num == 5)
{
val = 156;
}
else if (num == 4)
{
val = 125;
}
else if (num == 3)
{
val = 96;
}
else if (num == 2)
{
val = 66;
}
else
{
val = 25;
}
return val;
}
}
The best way to approach this is using a CardLayout.
Notes
A button with an ActionListener is far better than a MouseListener over a rectangle.
The button will show focus when the mouse is pointed at it, or the component is tabbed to via the keyboard.
The button is keyboard accessible.
The button has facility to support multiple icons built in (e.g. for 'initial look', focused, pressed etc.)
White space in the GUI is provided around the menu panel and game by adding an EmptyBorder
The button is made larger by setting a margin.
Adjust margins, borders and preferred size according to need. These sizes were set by me so as not to make the screenshots too large.
See more tips in the code comments.
Code
Here is the MCTaRE (Minimal Complete Tested and Readable Example) that produced the above screenshots.
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class PipesGame {
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
// the GUI as seen by the user (without frame)
final CardLayout cl = new CardLayout();
final JPanel gui = new JPanel(cl);
// remove if no border is needed
gui.setBorder(new EmptyBorder(10,10,10,10));
JPanel menu = new JPanel(new GridBagLayout());
JButton playGame = new JButton("Play!");
ActionListener playGameListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
cl.show(gui, "game");
}
};
playGame.addActionListener(playGameListener);
Insets margin = new Insets(20, 50, 20, 50);
playGame.setMargin(margin);
menu.add(playGame);
gui.add(menu);
cl.addLayoutComponent(menu, "menu");
JPanel pipes = new Pipes();
gui.add(pipes);
cl.addLayoutComponent(pipes, "game");
JFrame f = new JFrame("Pipes Game");
f.add(gui);
// Ensures JVM closes after frame(s) closed and
// all non-daemon threads are finished
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// See https://stackoverflow.com/a/7143398/418556 for demo.
f.setLocationByPlatform(true);
// ensures the frame is the minimum size it needs to be
// in order display the components within it
f.pack();
// should be done last, to avoid flickering, moving,
// resizing artifacts.
f.setVisible(true);
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency
SwingUtilities.invokeLater(r);
}
}
class Pipes extends JPanel {
Pipes() {
setBackground(Color.BLACK);
setForeground(Color.WHITE);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString("Pipes game appears here..", 170, 80);
}
#Override
public Dimension getPreferredSize() {
// adjust to need
return new Dimension(500,150);
}
}
"Is there a way for me to add my GameMenu jpanel to my jframe, and then replace it with the Pipes jpanel?"
As other have suggested, for this you want a CardLayout. It is very simple to you. Personally, I always wrap my CardLayout in a JPanel rather than the JFrame, just force of habit.
What you want to do is have a mainPanel that will have the CardLayout
CardLayout card = new CardLayout();
JPanel mainPanel = new JPanel();
Then you want to add your panels to the mainPanel. What the CardLyaout does is layer the panels, making just one visible at a time. The first one you add, will the in the foreground. Also when you add the panel, you'll also want to issue it a key it can be called from. The key, can be any String you like.
mainPanel.add(gameMenu, "menu");
mainPnael.add(pipes, "pipe");
Now gameMenu is the only panel shown. To show pipes, all you do is use this method
public void show(Container parent, String name) - Flips to the parent that was added to this layout with the specified name, using addLayoutComponent. If no such component exists, then nothing happens.
So you'd use, card.show(mainPanel, "pipes");
Whatever even you want to trigger the showing of pipes, just add that line in that event handler. You could add a button or something to the GameMenu that will allow movement to the Pipes panel.
This works with a mouse click on the menu. You can change it later, to a click on some button or whatever you want.
I added a MouseListener to the Game class. When the user presses the mouse on the menu JPanel, it adds the Pipes JPanel to JFrame and calls the pack method.
Game.java:
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class Game {
GameMenu menu = new GameMenu();
Pipes game;
boolean start = false;
JFrame f;
Rectangle2D menuRect = new Rectangle2D.Double(20, 20, 60, 40);
public Game() {
f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(menu);
f.setTitle("Pipe Game");
f.setResizable(false);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
menu.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
Point click = new Point(e.getX(), e.getY());
System.out.println("Clicked on the Panel");
if(menuRect.contains(click))
{
System.out.println("Clicked inside the Rectangle.");
start = true;
menu.setVisible(false);
game = new Pipes();
f.add(game);
f.pack();
Timer timer = new Timer(10, new ActionListener() { //pipe speed
#Override
public void actionPerformed(ActionEvent e) {
game.move();
}
});
timer.start();
Timer refresh = new Timer(30, new ActionListener() { //refresh rate
#Override
public void actionPerformed(ActionEvent e) {
game.repaint();
}
});
refresh.start();
}
}
#Override
public void mouseReleased(MouseEvent e) {
}
});
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Game();
}
});
}
}

Create a custom function that returns JLabel to main JFrame?

I hope I can remember to include all my details so here it goes.
I'm working with Java and I'm creating my own interface with the main window being a JFrame, the background is attached to the JFrame with a Background image(as JLabel) that fits exactly with the window. Then I have an image that is attached to the background Jlabel to act as a "start" button. My problem is I'd like to create a custom class that will facilitate each buttons functions inside its own class.
so instead of having functions in the main class that will react to the buttons, I'd like to make a class that can be added to the background... here is my code maybe someone could give me an example and I can figure out the rest or point me in the right direction.
The following code contains the original, please provide an example of how you would change it to encapulate eventlisteners in its own class for the Jlabel button
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class pipboy{
public static void main(String[] args){
pipboy pipboy_os = new pipboy();
pipboy_os.runmain();
}
public void runmain(){
//Create and set up the window.
JFrame frame = new JFrame("PIPBOY Research v0.0.03");
//background
ImageIcon background = new ImageIcon("UI/background/default.png");
JLabel label=new JLabel(background);
//radiation animated
ImageIcon animated_loading = new ImageIcon("UI/icon/loading/loading.png");
JLabel animated_icon = new JLabel(animated_loading);
animated_icon.setSize(128, 128);
animated_icon.setLocation(300, 125);
//Buff arm guy icon
ImageIcon icon_loading = new ImageIcon("UI/icon/34.png");
JLabel icon = new JLabel(icon_loading);
icon.setSize(128, 128);
icon.setLocation(300, 50);
label.add(icon);
label.add(animated_icon);
frame.add(label);
//Display the window.
frame.pack();
frame.setVisible(true);
//Full screen
frame.setSize(800,480);
frame.setExtendedState(Frame.MAXIMIZED_BOTH);
//Set default close operation for JFrame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//This is the handler class i made but i want it in its own class with the buff arm icon picure so it can do something specific when the image is pressed
HandlerClass handler = new HandlerClass();
frame.addMouseListener(handler);
frame.addMouseMotionListener(handler);
}
private static class HandlerClass implements MouseListener, MouseMotionListener{
public void mouseClicked(MouseEvent event){
System.out.println(String.format("Clicked at %d,%d", event.getX(), event.getY()));
}
public void mousePressed(MouseEvent event){
}
public void mouseReleased(MouseEvent event){
}
public void mouseEntered(MouseEvent event){
}
public void mouseExited(MouseEvent event){
}
public void mouseDragged(MouseEvent event){
}
public void mouseMoved(MouseEvent event){
}
}
}
Apparently I didn't know how polymorhpism worked in Java but here is my solution (with some names altered)
import javax.swing.*;
class GUItests{
public JFrame mainContainerFrame;
public static void main(String[] args){
GUItests mainController = new GUItests();
mainController.startGUI();
}
public void startGUI(){
mainContainerFrame = new JFrame("test Frame");
mainContainerFrame.setSize(800,480);
mainContainerFrame.pack();
mainContainerFrame.setVisible(true);
mainContainerFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel customButtonVar = customButton();
mainContainerFrame.getContentPane().add(customButtonVar);
}
public JLabel customButton(){
JLabel icon = new JLabel("testing");
icon.setSize(128, 128);
icon.setLocation(300, 50);
return icon;
}
}

Categories

Resources