I am trying to add a JPanel to a JLayeredPane with only partial success. I am able to see both of the panels separately, but not when I add them together. When I put them both together, only the DEFAULT_LAYER shows. Any thoughts would be great.
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.ImageIcon;
import javax.swing.JLayeredPane;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.*;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Container;
import java.awt.Component;
import java.awt.Insets;
import java.util.ArrayList;
import java.awt.LayoutManager;
public class ImageEditorView
{
public static int dimensionWidth = 1280;
public static int dimensionHeight = 640;
private Color currentColor = Color.WHITE;
private JLayeredPane layeredPane;
private JPanel createEditPanel()
{
final CirclePanel editPanel = new CirclePanel();
//editPanel.setLayout(new CircleLayout(true));
editPanel.setBounds(50, 0, 150, 150);
editPanel.setOpaque(true);
return editPanel;
}
private JPanel createImageView()
{
JPanel imageView = new JPanel(new GridBagLayout());
imageView.setPreferredSize(new Dimension(dimensionWidth, dimensionHeight));
imageView.setBounds(0, 0, dimensionWidth, dimensionHeight);
imageView.setBackground(currentColor);
return imageView;
}
private void addToLayeredPane(JComponent component, int level)
{
//This prints out what is expected. values of 1 and 100 respectfully
System.out.println("The level has a value of " + level);
layeredPane.add(component, level);
}
public void createAndShowGUI()
{
JFrame f = new JFrame("ImageEditor");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
layeredPane = new JLayeredPane();
//Both createImageView and createEditPanel return with the type JPanel
addToLayeredPane(createImageView(), JLayeredPane.DEFAULT_LAYER);
addToLayeredPane(createEditPanel(), JLayeredPane.PALETTE_LAYER);
f.setSize(dimensionWidth, dimensionHeight);
f.setContentPane(layeredPane);
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
}
class CirclePanel extends JPanel
{
#Override
protected void paintComponent(Graphics g)
{
g.drawOval(0, 0, g.getClipBounds().width, g.getClipBounds().height);
}
}
A JPanel is opaque by default. So you will only see the panel that has been added to the top layer. Try:
panel.setOpaque(false);
on the top panel.
If you need more help then post a proper SSCCE that demonstrate the problem. The code you posted does not compile and therefore is not executable.
Edit:
The problem is your addToLayeredPane(...) method. You are using a layer parameter of "int". It needs to be Integer.
Since you are adding the component using an int value the component is added to the panel normally and is painted in its ZOrder, which basically means the last component added is painted first so your "imageview" is painted on top of the "editview".
Also, you still are not using setOpaque(false) on the "editpanel" as I suggested. The code will only appear to work because you are NOT doing custom painting properly. You should always invoke super.paintComponent(g) at the start of your painting method. This will automatically paint the background which is why you need to make the panel transparent.
Related
I created a graphing utility using canvas. Currently, information is inputted through the console. However, I want to make the program more presentable by adding inputs via JTextField and JButtons. Is there any way I can do that?
something like this:
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class JFrameWithCanvas extends JFrame {
private Canvas canvas = new Canvas();
public JFrameWithCanvas() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel pnlToolbar = new JPanel();
pnlToolbar.add(new JTextField(10));
pnlToolbar.add(new JButton("foo"));
getContentPane().add(pnlToolbar, BorderLayout.PAGE_START);
canvas.setBackground(Color.MAGENTA);
getContentPane().add(canvas, BorderLayout.CENTER);
canvas.setPreferredSize(new Dimension(300, 300));
pack();
setLocationRelativeTo(null); // center it on the screen
}
public static void main(String[] args) {
new JFrameWithCanvas().setVisible(true);
}
}
I'm writing the UI for the pet project I've been doing and I'm experimenting with java Graphics, drawing lines, shapes, and stuff. And, I've been trying all day to insert a simple line in a Jpanel but still haven't figured out what went wrong.
package thuake;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.Paint;
import java.awt.Polygon;
import java.awt.geom.Line2D;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class Main extends JFrame{
static Dimension DEFAULT_SIZE = new Dimension(530, 320);
static JFrame Frame1 = new JFrame();
static JScrollPane spanel = new JScrollPane();
static JPanel Panel1 = new JPanel();
static MenuBar menu = new MenuBar();
static Menu menusub1 = new Menu("Open");
public static void main(String[] args)
{
start();
}
public static void start (){
Frame1.setLayout(new FlowLayout(FlowLayout.CENTER,5,10));
spanel.add(new draw());
Frame1.add(spanel);
spanel.setBorder(BorderFactory.createLineBorder(Color.black));
spanel.setPreferredSize(new Dimension(500, 500));
Frame1.add(new JButton("ad"));
Frame1.add(new JButton("ad"));
Frame1.add(new JButton("ad"));
Frame1.add(new draw());
Frame1.setMenuBar(menu);
menu.add(menusub1);
Frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Frame1.pack();
spanel.setVisible(true);
Frame1.setVisible(true);
System.out.println();
}
static class draw extends Component {
public void paint(Graphics g) {
Graphics2D line = (Graphics2D)g;
line.drawLine(0, 0, 120, 120);
}
}
}
Here is a basic framework you should follow when you are doing graphics.
Key points are:
Don't extend JFrame, use a separate instance.
Override paintComponent() and not paint()
Start the process in the EDT. Do all swing stuff in the EDT.
Do not paint outside the EDT or with a graphics context that you retrieved yourself. Always use the one from paintComponent()
Set the width and height (dimension) for the panel and not the JFrame. The reason being that those dimensions on the JFrame include the thick borders. For the JPanel you get the full width.
At some point you can modify this and add additional components to the JFrame and/or JPanel. For now this should provde a basis for experimenting.
You should also read up on this and anything I omitted shown below. Check out the Java Tutorials for more on information on graphics and painting.
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Template extends JPanel {
final static int height = 500;
final static int width = 500;
final static String title = "title";
JFrame frame = new JFrame(title);
public static void main(String[] args) {
// start on the EDT
SwingUtilities.invokeLater(() -> new Template().start());
}
public Template() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(this); // add the panel
setPreferredSize(new Dimension(width, height));
frame.pack();
// center on screen
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void paintComponent(Graphics g) {
super.paintComponent(g); // always do this
Graphics2D g2d = (Graphics2D) g.create();
// Optional. It averages the edges of a figure to give a smoothing effect
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// do something here.
g2d.setColor(Color.red);
g2d.fillRect(200,200,100,100);
g2d.dispose();
}
}
I just started to work with Java.
I have no problems with creating window,button and any graphics.
But, i cant make window with many buttons, graphics and text boxes.
When i add buttons to my window i cant see graphics.
How can i do it?
code:
package today;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.*;
import java.awt.event.*;
import java.awt.Graphics;
public class mybuttonapp extends JFrame
{
private mybuttonapp()
{
}
public static void main(String[] args)
{
// TODO Auto-generated method stub
//new mybuttonapp().setVisible(true);
//--
JFrame f=new JFrame("Button Example");
f.setVisible(true);
f.setSize(900, 600);
//f.setLayout(null);
f.setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel p1 = new JPanel();
p1.setBackground(Color.GREEN);
p1.setPreferredSize(new Dimension (100,100));
p1.setVisible(true);
f.add(p1);
My2d paint1 = new My2d();
JButton b1=new JButton("Click Here");
b1.setBounds(10,10,100,50);
p1.add(b1);
p1.add(paint1);
}
code 2:
package today;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.*;
import java.awt.event.*;
public class My2d extends JComponent
{
public void paint (Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
Ellipse2D.Double circle = new Ellipse2D.Double(300,300,50,50);
g2.fill(circle);
}
}
I think what you want to look at are layouts in swing. If I get what you ask and what you're doing you are overwriting whatever you set first.
https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
This link provides explanations to all of the swing layouts.
You need to check how LayoutManagers work in Java. They help you to put the elements in the right place within your container (JFrame/JPanel).
https://docs.oracle.com/javase/tutorial/uiswing/layout/layoutlist.html
Normally I work with a combination of BorderLayout and GridBagLayout, since it is quite flexible - but many users feel GridBagLayout is too complicated, especially for beginners.
So I'm looking at a tutorial here: http://zetcode.com/tutorials/javagamestutorial/basics/
At the very end, they show how to set an image as a background (which is simple). They use 2 codes: Board.java and Image.java (which I've copied below for your convenience).
For some reason, I can't seem to add a JButton to my GUI?
I tried adding the following code to Image.java after the line Image Main = new Image(); , but I can't figure out why it doesn't work. Normally I can just add a JButton to a JPanel using the add command and set the panel to visible with setVisible(true).
JButton start;
start = new JButton("Click Me");
Main.getContentPane().add(start);
I also tried adding a similar code to Board.java instead just to see if it'd work - and it of course didn't. How come my JButton won't show up? I know I'm doing something wrong, but I can't figure it out. Can someone help?
(1) Board.java
package bardejov;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
public class Board extends JPanel {
Image bardejov;
public Board() {
ImageIcon ii = new ImageIcon(this.getClass().getResource("bardejov.jpg"));
bardejov = ii.getImage();
}
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(bardejov, 10, 10, null);
}
}
(2) Image.java
package bardejov;
import javax.swing.JFrame;
import javax.swing.JButton;
public class Image extends JFrame {
public Image() {
add(new Board());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(280, 240);
setLocationRelativeTo(null);
setTitle("Bardejov");
setVisible(true);
}
public static void main(String[] args) {
Image Main = new Image();
}
}
You need to first create a JPanel with Board and Button laid out correctly. Then set this JPanel as the content pane for the JFrame. You are trying to add two different components to the Frame via different methods which is causing the confusion. If you resize the frame may be you will see the button you added in the background.
When I comment out frame.add(hidden) it only shows the text area. When I don't comment it out, it only shows a large gray box with a grayed out Scrollbar.
import java.util.Scanner;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Panlindrome{
public Panlindrome(){
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Panlindrome?");
frame.setSize(240,320);
//frame.setLayout(new GridLayout(3,1));
JTextArea inputText = new JTextArea(30,1);
inputText.setLineWrap(true);
JScrollPane hidden = new JScrollPane(inputText);
hidden.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
frame.add(inputText);
//frame.add(hidden);
frame.setVisible(true);
}
public static void main(String[] args){
Panlindrome check = new Panlindrome();
}
}
Don't add inputText to the frame; only add hidden.
The content of the scroll pane is already a child of the scroll pane. If you also try to add it to the frame (actually the frame's content pane, but whatever) as well, it will be in two places at once, which doesn't work.