I'm trying to create a basic game where a character can move an image on the screen, which is on top of a background image. Here is my main method, where I'm setting all of this up:
public static void main(String[] args){
EventQueue.invokeLater(new Runnable(){
public void run(){
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Stuff");
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
// Create a panel with a component to be moved
JPanel character = new JPanel();
JLabel component = new JLabel();
component.setIcon(new ImageIcon("C:/Users/Cory/Desktop/img/eagle.jpg"));
component.setSize( component.getPreferredSize() );
component.setLocation(200, 200);
component.repaint();
JButton left = addMotionSupport( component );
character.add(component);
character.repaint();
//end moveable
frame.add( character );
frame.repaint();
JPanel background = new JPanel();
JLabel contentPane = new JLabel();
contentPane.setIcon(new ImageIcon("C:/Users/Cory/Desktop/img/background.png"));//sets contentPane to display the background
contentPane.setSize(contentPane.getPreferredSize());
background.add(contentPane);
background.repaint();
frame.add(background);
frame.repaint();
//frame.add(left, BorderLayout.SOUTH);
frame.setSize(1000, 800);
frame.setVisible(true);
}
});
}
The issue I'm running into is the following. I am able to display the background image OR the moveable image, but not both. What I believe is happening is that the two jpanels are 'overlapping' on top of each other - is this correct? How would I fix something like this? I browsed through the API a bit and I found something called a JLayeredPane, but I'm not sure how to use that and if it is even the correct tool. Any insight you provide would be most appreciated.
N.B. the 'addMotionSupport' method only adds a KeyListener to the passed argument.
a character can move an image on the screen, which is on top of a background image.
Then you need to add the character to the background.
So the basic code should be:
JLabel character = new JLabel(...);
character.setSize( character.getPreferredSize() );
JLabel background = new JLabel(...);
background.add( character );
frame.add( background );
You don't need the extra panels. You can add a label directly to the frame.
You need to set the size of the character label because a JLabel does not use a layout manager. So in this case you are responsible for managing the size and location of the character when you add it to the background component. The location will default to (0, 0);
You don't need all the frame.repaint() statements, the frame will be painted when it is made visible. Don't use frame.setSize(), instead use frame.pack(). Then the frame will be set to the size of the background image.
Related
I am adding JLabels from an Arraylist to a JPanel and they will only display if i set a layout on the panel but i want to set the location of the labels myself when i try panel = new JPanel(null); all labels are not displayed.
Frame:
public static void Frame(){
panel = new JPanel(null);
JFrame frame = new JFrame("New");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.pack();
frame.setSize(400,400);
frame.add(panel);
}
ArrayList iteration that adds labels to panel
private static void printArray() {
for(int i = 0; i < food.size(); i++){
component = new JLabel(new Food(food.get(i).getColor(),
food.get(i).getIconHeight(), food.get(i).getIconWidth(),
food.get(i).getLocationX(), food.get(i).getLocationY()));
panel.add(component);
component.setLocation(food.get(i).getLocationX(),
food.get(i).getLocationY());
}
}
I can see from Debug it is definitely getting the location information, so why is it not putting it in this location.
The reason to set layout as null is so i can update the position of the label so i can "move" it around with keyboard input
The first thing you need to do is understand what job the layout manager actually does, because if you're going to remove it, you're going to need to take over it's work.
Layout managers are responsible for determining both the size and position of the components. They do this through a variety of means, but can make use of the getPreferred/Minimum/MaximumSize methods of the components.
So this would suggest you need to make your own determinations about these values, for example...
component = new JLabel(new Food(food.get(i).getColor(),
food.get(i).getIconHeight(), food.get(i).getIconWidth(),
food.get(i).getLocationX(), food.get(i).getLocationY()));
component.setSize(component.getPreferredSize());
component.setLocation(food.get(i).getLocationX(), food.get(i).getLocationY());
I'd also recommend using the Key Bindings over KeyListener, it doesn't suffer from the same focus related issues
I'm programming right now a Chomp Game for Uni. Everything works fine but the Label at the bottom. Its background is supposed to fill out the entire bottom. In the attachment you can see how it instead looks now. I tried setting the minimum and the preferred size of the label. The Height is changing but the width just stays adjusted to the text. How can I change that?
Note: The snippet only contains the setting up of the Frame and Panels in a custom method and not the main class.
private void init()
{
JFrame fenster = new JFrame();
this.spielfeld = new SpielfeldPanel(M, N);
this.anzeige = new SpielerAnzeigeLabel(this.spieler);
JPanel panel = new JPanel();
BoxLayout boxlayout = new BoxLayout(panel,BoxLayout.Y_AXIS);
panel.setLayout(boxlayout);
fenster.setTitle("Chomp");
fenster.setSize(1000,700);
panel.setPreferredSize(new Dimension(1000, 60));
Dimension d = new Dimension(getPreferredSize());
panel.setMinimumSize(d);
panel.add(spielfeld);
panel.add(anzeige);
fenster.add(panel);
this.spielfeld.setVisible(true);
this.anzeige.setVisible(true);
panel.setVisible(true);
fenster.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
A BoxLayout respects the width of the component to the label is displayed at its preferred width/height.
A JFrame uses a BorderLayout by default. So just add the label to the frame independently of the panel:
//panel.add(anzeige);
//fenster.add(panel);
fenster.add(panel, BorderLayout.CENTER);
fenster.add(anzeige, BorderLayout.PAGE_END);
The PAGE_END constraint respects the height but makes the width equal to the space available. Read the section from the Swing tutorial on How to Use BorderLayout for more information and examples.
I am having a bit of trouble with nested JPanels playing a video. I have an AVPlayer class extend JPanel which plays up to 4 videos simultaneously. Each video is played inside its own canvas which is inside its own JPanel. All the panels are then put into the AVPlayer panel. But when I try to play the videos all I get is a black square.
I'm not sure what the actual problem in my bigger program is but I think I can solve it if I can get the videos to play using the second bit of code below. Can someone tell me why the first bit of code is properly able to display all the videos, but the second one is not.
Code that works:
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setVisible(true);
AVPlayer player = new AVPlayer();
frame.getContentPane().add(player);
frame.revalidate();
String[] path = {"(ei)ga_00.mp4", "ei-utsu(ru)_00.mp4", "video.mp4"};
player.playVideo(path);
Code that shows one small black square
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setVisible(true);
AVPlayer player = new AVPlayer();
JPanel panel = new JPanel();
panel.add(player);
frame.getContentPane().add(panel);
frame.revalidate();
String[] path = {"(ei)ga_00.mp4", "ei-utsu(ru)_00.mp4", "video.mp4"};
player.playVideo(path);
Change JPanel panel = new JPanel(); to JPanel panel = new JPanel(new BorderLayout());
Your AVPlayer should also override the getPreferredSize method of JPanel and return the "preferred size" of the component, this way the layout managers have some hope of actually been able to do there jobs
See Laying Out Components Within a Container for more details
Beware that vlcj's primary video surface is a heavy weight component and mixing them on light weight containers can generate some undesirable effects
I am new to Swing. I am building a JFrame with a JScrollPane inside it using Eclipse IDE. Inside of the JScrollPane is a JPanel in Border Layout. I tried to add a JButton (called "submitAnswers") to the JFrame using the code below, but for some reason the button only appears at the end of the frame on my computer, but not on other computers (my friend tried it on his Mac and I tried it on a separate Windows OS like mine). Some proposed solutions that I have tried and from other sites that have not worked include:
Use the pack() method. Reason: since the preferred size of the JPanel is much longer in height than the JFrame (hence I employed a JScrollPane), packing the JFrame only causes the text to be not visible on the desktop.
Place button on content JPanel. Reason: I don't know. It just wouldn't appear on another desktop computer or my friend's mac computer.
Use BorderLayout.SOUTH instead of BorderLayout.PAGE_END. Reason: There was absolutely no change. The button would still be visible on my computer, but invisible on others.
Place button directly on JFrame. Reason: I don't know.
In addition, my JFrame is nested within a static method; hence, I've only included the relevant code for the specific method I'm having issues with.
Has anyone had this issue before? I would really appreciate your insight.
Code:
public static void createTestPage() {
JFrame testFrame = new JFrame("testing...1,2,3");
//Customizes icon to replace java icon
try {
testFrame.setIconImage(ImageIO.read(new File("src/icon.png")));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//Centers location of introFrame to center of desktop
Dimension screenDimensions = Toolkit.getDefaultToolkit().getScreenSize();
testFrame.setLocation(screenDimensions.width / 16,screenDimensions.height / 14);
//Size and display the introFrame.
Insets insets = testFrame.getInsets();
//Format size of screen itself
testFrame.setSize(1200 + insets.left + insets.right,
400 + insets.top + 250 + insets.bottom);
//Temporarily set screen so that it cannot be resized
testFrame.setResizable(false);
//Set background color of testFrame
testFrame.getContentPane().setBackground(new Color(75, 0, 130));
testFrame.setLayout(new BorderLayout());
//Set layout of testFrame
testFrame.setLayout(new BorderLayout(10, 1));
//Test content
JPanel testContentPanel = new JPanel();
testContentPanel.setBackground(new Color(75, 0, 130));
testContentPanel.setSize(new Dimension(900,2060));
testContentPanel.setPreferredSize(new Dimension(900, 2060));
//Test content pane layout
testContentPanel.setLayout(new BoxLayout(testContentPanel, BoxLayout.PAGE_AXIS));
//Create panel to hold instructions text
JPanel instructionsPanel = new JPanel();
instructionsPanel.setBackground(new Color(75, 0, 130));
instructionsPanel.setLayout(new BorderLayout(10,1));
//Create JPanel for submit answers button
JPanel submitAnswersPanel = new JPanel(new BorderLayout());
submitAnswersPanel.setBackground(new Color(75, 0, 130));
submitAnswersPanel.setVisible(true);
//Create button to submit personality test answers
JButton submitAnswers = new JButton("Submit Answers");
submitAnswers.setVisible(true);
submitAnswers.setBorder(new EmptyBorder(10, 400, 10, 400));
//Add submitAnswers button to panel
submitAnswersPanel.add(submitAnswers);
//Add submitAnswersPanel to test content panel
testContentPanel.add(submitAnswersPanel);
//Create scroll pane to allow for scrollable test (contents cannot fit one page)
JScrollPane testScrollPane = new JScrollPane();
testScrollPane.setViewportView(testContentPanel);
//Get rid of horizontal scroll bar and add vertical scrollbar
testScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
testScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
//Speed up scrolling
testScrollPane.getVerticalScrollBar().setUnitIncrement(16);
testFrame.add(testScrollPane);
//Experiment to show button
testFrame.setVisible(true);
}
I've refactored your code a little to use method to create the individual components of the GUI. You can find the full code at this ideone link
What I saw when I first copied your code to my machine was that the only thing visible was the button. So I create all the components in their own methods and then added them to the frame and panels using the Border Layout. This then enabled me to put the instructions in the NORTH sections, the button in the SOUTH section and then the main bits would go in the CENTER section.
One thing to note about the sections: (From the documentation)
The components are laid out according to their preferred sizes and the constraints of the container's size. The NORTH and SOUTH components may be stretched horizontally; the EAST and WEST components may be stretched vertically; the CENTER component may stretch both horizontally and vertically to fill any space left over.
So you should add the component you want to scale in size to the CENTER section.
My main method now looks like this:
public static void main(final String[] args) {
final JButton submitAnswers = createSubmitAnswersButton();
final JPanel instructionsPanel = createInstructionsPanel();
final JPanel testContentPanel = createContentPanel();
testContentPanel.add(instructionsPanel, BorderLayout.NORTH);
testContentPanel.add(submitAnswers, BorderLayout.SOUTH);
final JScrollPane scrollingContentPane = createScrollPaneFor(testContentPanel);
final JFrame testFrame = createJFrame();
testFrame.add(scrollingContentPane, BorderLayout.CENTER);
testFrame.setVisible(true);
}
I am a newbie, I have a question. I am trying to use Eclipse to write a Java windows application, in which I will have a main window, which will contain several things, like a dashboard sort of thing, and it will have buttons, for example to add a record to a database, and this button when pressed, will open a new relevant window on top.
I tried to start, I wrote this code in Java, and for some reason, the button is in the size of the frame...full screen ! How do I fix it ?
Can you suggest me better ideas for a design than what I specified ?
Thank you
public class MainClass {
public static void main(String[] args) {
// TODO Auto-generated method stub
JFrame jfrm = new JFrame("Frame1");
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
jfrm.setSize(screenSize.width, screenSize.height);
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel jlab = new JLabel("Hello");
jfrm.add(jlab);
JButton button = new JButton("Button");
button.setSize(new Dimension(50, 50));
button.setLocation(500, 350);
jfrm.getContentPane().add(button);
jfrm.setVisible(true);
}
Add a layout to the JFrame first. For example FlowLayout:
jfrm.setLayout(new FlowLayout());
"I tried to start, I wrote this code in Java, and for some reason, the button is in the size of the frame...full screen ! How do I fix it ?"
The reason the button stretches is because JFrame has a default BorderLayout that does not respect the preferred sizes of child components.
The solution is to set the Layout Manager to layout that does respect preferred sizes. The image blow from this example shows the most common Layout Managers and show visually which one respect the preferred size of child components.
Also, the BorderLayout is also the reason your JLabel does not show. By default, every component that is added to a BorderLayout without a position specified e.g. BorderLayout.SOUTH, will automatically be placed in the BorderLayout.CENTER position. Each position may only have one component. So when you add the JLabel it goes to the CENTER, but when you add the JButton, it also goes the CENTER, kicking out the JLabel.
If you've never encountered Layout Managers, this is probably all confusing to you. You should take the time to go over How to Layout Components Within a Container
You need to use some form of layoutmanager, you can use this information: http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
You must use Layout manager.
Use this code..
public static void main(String[] args)
{
JFrame jfrm = new JFrame("Frame1");
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
jfrm.setSize(screenSize.width, screenSize.height);
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel jlab = new JLabel("Hello");
jfrm.add(jlab);
JButton button = new JButton("Button");
button.setSize(new Dimension(50, 50));
button.setLocation(500, 350);
jfrm.add(button);
jfrm.setVisible(true);
jfrm.setLayout(new FlowLayout());
jfrm.pack();
you forgot to add pack(). so use this code to get Jlabel and JButtion side by side.
Thanks...