I'm trying to simulate a drop shadow using non-expensive drawing rectangles, around a JFrame that has a menu bar, but the shadow is showing around the lower part excluding the menu bar.
Any idea how to achieve the effect on the whole window?
package com.dropshadow;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.border.EmptyBorder;
import org.nuiton.jaxx.runtime.swing.ComponentMover;
import org.nuiton.jaxx.runtime.swing.ComponentResizer;
public class DropShadowMenu {
public static void main(String[] args) {
initFrame();
}
private static void initFrame() {
final DropShadowTool shadow = new DropShadowTool();
JFrame frame = new JFrame() {
private static final long serialVersionUID = -512601712971605848L;
#Override
public void paint(Graphics g) {
super.paint(g);
shadow.applyShadow(this, (Graphics2D) g);
}
};
frame.setUndecorated(true);
frame.setBackground(new Color(255, 255, 255, 0));
frame.setPreferredSize(new Dimension(400, 600));
JPanel contentPane = new JPanel() {
private static final long serialVersionUID = -4799881378955761842L;
#Override
public void paint(Graphics g) {
super.paint(g);
shadow.applyShadow(this, (Graphics2D) g);
}
};
contentPane.setBorder(new EmptyBorder(20, 20, 20, 20));
contentPane.setLayout(new BorderLayout());
frame.setContentPane(contentPane);
contentPane.setBackground(new Color(0,0,0,0));
JPanel content = new JPanel();
contentPane.add(content);
JMenuBar menuBar = new JMenuBar();
menuBar.setBorder(new EmptyBorder(0,20,0,20));
menuBar.setBackground(new Color(255, 0, 255, 255));
frame.setJMenuBar(menuBar);
JPanel menuPanel = new JPanel();
menuPanel.setBorder(BorderFactory.createLineBorder(Color.red));
menuPanel.setLayout(new BorderLayout());
JMenu file = new JMenu("File");
file.setMnemonic('f');
JMenuItem exit = new JMenuItem("Exit");
exit.setMnemonic('x');
exit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X,InputEvent.ALT_DOWN_MASK));
menuBar.add(file);
file.add(exit);
exit.addActionListener(e ->
{
System.out.println("Exiting - Bye!");
System.exit(0);
} );
JMenu menu = new JMenu("Menu 1");
menuBar.add(menu);
menu.add(new JMenuItem("Item 1"));
menu.add(new JMenuItem("Item 2"));
JMenu subMenu = new JMenu("SubMenu 1");
subMenu.add(new JMenuItem("Item 3"));
subMenu.add(new JMenuItem("Item 4"));
menuBar.add(Box.createHorizontalGlue());
JButton x = new JButton("X");
x.setBorder(null);
x.setBackground(new Color(0,0,0,0));
menuBar.add(x);
x.addActionListener(e -> System.exit(0));
menu.add(subMenu);
content.setLayout(new BorderLayout());
JButton button = new JButton("bla blah");
button.addActionListener(e->System.out.println("bla bla button"));
content.add(button, BorderLayout.SOUTH);
content.setBackground(new Color(255,255,255));
JButton jx = new JButton(". X .");
jx.setBackground(new Color(255,255,255));
menuPanel.add(jx, BorderLayout.EAST);
jx.addActionListener(e -> System.exit(0));
ComponentMover cm = new ComponentMover();
cm.registerComponent(frame);
ComponentResizer cr = new ComponentResizer();
cr.registerComponent(frame);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
private static List<Color> colors = new ArrayList<Color>();
static {
for (int i=0;i<20;i++) {
colors.add(new Color(0, 0, 0, 5*i));
}
}
private static class DropShadowTool {
private void applyShadow(Container c, Graphics2D g) {
if(c.getName().equals("Charbel"))
System.out.println(c);
Insets insets = c.getInsets();
System.out.println(insets);
Dimension size = c.getSize();
int x0 = 0;
int xi = insets.left;
int y0 = 0;
int yi = insets.top;
int width0 = size.width;
int widthi = size.width - xi - insets.right;
int height0 = size.height;
int heighti = size.height - yi - insets.bottom;
int last = 0;
for (int i = 0; i < insets.left; i++) {
last = i;
drawLines(g, x0, y0, width0, height0, i);
}
drawLines(g, x0, y0, width0, height0, last);
}
private void drawLines(Graphics2D g, int x0, int y0, int width0, int height0, int i) {
int x = x0 + i;
int y = y0 + i;
int width = width0 - i - i;
int height = height0 - i - i;
g.setColor(colors.get(i % colors.size()));
g.drawRect(x, y, width, height);
}
}
}
I would suggest that your drop shadow is just is just a custom Border and should be implemented as such.
Then you should be able to add the DropShadowBorder to any Swing component without doing any custom painting on the component.
Then I would suggest you can set the Border of the JRootPane. The root pane manages both the menu bar and the content pane at a higher level so the border should be around both components.
Read the section from the Swing tutorial on The Root Pane.
Related
I'm also having problem with button.addActionListener(null); inside the () should be "this" but you can't use this in a static context which I don't have an idea of what it means. The core problem of this thread is the JButton and JLabel not showing up when I run the Program. If you have any suggestion where I can read more in depth to have a deeper understanding of JLabels, JFrame, JButton and JPanel please do tell me and I would appreciate that as I am completely new to Programming as a whole. Thank you for any feedbacks. :)
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class GUI implements ActionListener {
private static int count = 0;
private static JLabel label;
public static void gui() {
System.out.println("Hello World!"); // For debugging.
JFrame frame = new JFrame();
JButton button = new JButton("Click");
button.addActionListener(null); // <--- One of my issue!
label = new JLabel("Total Clicks: 0");
Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
int x = (int) ((dimension.getWidth() - frame.getWidth()) / 2);
int y = (int) ((dimension.getHeight() - frame.getHeight()) / 2);
int width = x;
int height = y;
int perf_x = (int) x - width/2;
int perf_y = (int) y - height/2;
frame.setLocation(perf_x, perf_y);
ImageIcon icon = new ImageIcon("icon.png");
JPanel panel = new JPanel();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(800,550);
frame.setTitle("Click Counter");
frame.setResizable(true);
frame.setIconImage(icon.getImage());
frame.getContentPane().setBackground(new Color(255, 255, 255));
frame.add(panel, BorderLayout.CENTER );
} // Method
public void actionPerformed(ActionEvent e) {
count++;
label.setText("Total Clicks: " + count);
}
} // Class
I have tried changing the JFrame in a different line to the upper sections of the code if that would make it work but no luck. Instead of a mouse clicker I was met with a blank program.
in this code i changed button.addActionListener(null); to button.addActionListener(new GUI());
new GUI() creates a new instance of the GUI class, which implements the ActionListener interface.
This means that GUI has implemented the required actionPerformed() method that gets called when the button is clicked.
i hope this will help you:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class GUI implements ActionListener {
private static int count = 0;
private static JLabel label;
public static void gui() {
System.out.println("Hello World!"); // For debugging.
JFrame frame = new JFrame();
JButton button = new JButton("Click");
button.addActionListener(new GUI()); // Set the ActionListener to this instance
label = new JLabel("Total Clicks: 0");
ImageIcon icon = new ImageIcon("icon.png");
JPanel panel = new JPanel();
panel.add(button);
panel.add(label);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(800,550);
frame.setTitle("Click Counter");
frame.setResizable(true);
frame.setIconImage(icon.getImage());
frame.getContentPane().setBackground(new Color(255, 255, 255));
frame.add(panel, BorderLayout.CENTER);
Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
int x = (int) ((dimension.getWidth() - frame.getWidth()) / 2);
int y = (int) ((dimension.getHeight() - frame.getHeight()) / 2);
int width = x;
int height = y;
int perf_x = (int) x - width/2;
int perf_y = (int) y - height/2;
frame.setLocation(perf_x, perf_y);
} // Method
public static void main(String[] args) {
gui();
}
public void actionPerformed(ActionEvent e) {
count++;
label.setText("Total Clicks: " + count);
}
} // Class
I am trying to get 2 objects to show on the screen using JFrame and I am trying to move them around. I got 1 object to appear on the screen and then I tried to get 2 of them on there, but I just can't get it to work
This is my Main
package animate;
import javax.swing.*;
import java.awt.*;
public class Main {
public static void main(String[] args){
//Square s = new Square(50, 100, 2);
//Square s2 = new Square(300, 50, 1);
JFrame frame = new JFrame();
JPanel panel = new JPanel();
frame.setSize(700, 350);
panel.setLayout(new FlowLayout());
panel.add(new Square(50, 100, 2));
panel.add(new Square(300, 50, 1));
frame.add(panel);
frame.setResizable(false);
frame.setTitle("hi");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
This is my square class(It's supposed to draw a square but I am using a circle for testing purposes for right now)
package animate;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import javax.swing.*;
public class Square extends JPanel implements ActionListener {
Timer t = new Timer(5, this);
double x, y, vel;
public Square(int x, int y, int vel){
this.x = x;
this.y = y;
this.vel = vel;
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
Ellipse2D circ = new Ellipse2D.Double(this.x, this.y, 40, 40);
g2.fill(circ);
t.start();
}
public void actionPerformed(ActionEvent e){
x += 0;
y += 0;
repaint();
}
#Override
public Dimension getPreferredDimension(){
return new Dimension(100, 540);
}
}
I need some help with my code; I have a program that will show the graph of Ohm's Law. The graph was showing before I put a save button. When i run the program, it will only show the everything except for the graph. Also, I have problems in saving the current and voltage array into a .txt file. Please help!
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.font.FontRenderContext;
import java.awt.font.LineMetrics;
import java.awt.geom.*;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.charset.Charset;
import static java.nio.file.Files.newBufferedWriter;
import java.nio.file.StandardOpenOption;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
public class DrawGraph extends JPanel {
double current[] = new double [999];
double voltage[] = new double [999];
final int TEXT = 20;
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int w = 400;
int h = 400;
g2.setStroke(new BasicStroke(3));
g2.drawLine(TEXT, TEXT, TEXT, h-TEXT);
g2.drawLine(TEXT, h-TEXT, w-TEXT, h-TEXT);
for(int x= 0; x<1000; x++ )
{
current[x]=x+1;
voltage[x]=x+1;
}
g2.setPaint(Color.red);
g2.setStroke(new BasicStroke(2));
g2.draw(new Line2D.Double(TEXT, h-TEXT, w-TEXT ,TEXT ));
// Draw labels.
g2.setPaint(Color.black);
Font font = g2.getFont();
FontRenderContext frc = g2.getFontRenderContext();
LineMetrics lm = font.getLineMetrics("0", frc);
float sheight = lm.getAscent() + lm.getDescent();
// Ordinate label.
g2.setFont(new Font("Century Gothic", Font.PLAIN, 15));
String s = "Voltage V";
float sY = TEXT + ((h - 2*TEXT) - s.length()*sheight)/2 + lm.getAscent();
for(int r = 0; r < s.length(); r++)
{
String letter = String.valueOf(s.charAt(r));
float swidth = (float)font.getStringBounds(letter, frc).getWidth();
float sX = (TEXT - swidth)/2;
g2.drawString(letter, sX, sY);
sY += sheight;
}
// Abcissa label.
s = "Current A";
sY = h - TEXT + (TEXT - sheight)/2 + lm.getAscent();
float swidth = (float)font.getStringBounds(s, frc).getWidth();
float sX = (w - swidth)/2;
g2.drawString(s, sX, sY);
//Gridlines
int b=TEXT+(((w-TEXT)-TEXT)/10);
g2.setPaint(Color.gray);
for(int a=1; a<=10; a++)
{
b+=36;
g2.setStroke(new BasicStroke(1));
g2.drawLine(b, h-TEXT, b, TEXT);
g2.drawLine(TEXT, b, w-TEXT, b);
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Ohm's Law");
JPanel panel = new JPanel(new BorderLayout(3,1));
JPanel titlepanel = new JPanel();
titlepanel.setPreferredSize(new Dimension(400,50));
JLabel title = new JLabel("OHM'S LAW");
title.setFont(new Font("Century Gothic", Font.BOLD, 25));
titlepanel.add(title);
panel.add(titlepanel,BorderLayout.NORTH);
JPanel graphpanel = new JPanel();
graphpanel.setBackground(Color.white);
graphpanel.setPreferredSize(new Dimension(420,420));
DrawGraph drawgraph = new DrawGraph();
graphpanel.add(drawgraph);
panel.add(graphpanel,BorderLayout.CENTER);
JPanel buttonpanel = new JPanel ();
buttonpanel.setPreferredSize(new Dimension(400,50));
JButton save = new JButton("SAVE");
save.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed (ActionEvent event)
{
JFrame parentFrame = new JFrame();
JFileChooser fileChooser = new JFileChooser();
fileChooser.setDialogTitle("Specify a file to save");
int userSelection = fileChooser.showSaveDialog(parentFrame);
if (userSelection == JFileChooser.APPROVE_OPTION)
{
java.io.File fileToSave = fileChooser.getSelectedFile();
try
{
fileToSave.createNewFile();
try (BufferedWriter writer = newBufferedWriter(fileToSave.toPath(), Charset.defaultCharset(), StandardOpenOption.WRITE))
{
writer.write("V=I\t R=1\r Voltage \t Current\n");
//writer.write("Material: " + material.getSelectedValue().toString()+"\r\nv = " + v + "\r\nE1 = " + e1 + "\r\nE2 = " + e2);
}
}
catch (IOException ex)
{
Logger.getLogger(DrawGraph.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Save as file: " + fileToSave.getAbsolutePath());
}
}
}
);
save.setFont(new Font("Century Gothic", Font.BOLD, 15));
buttonpanel.add(save);
panel.add(buttonpanel, BorderLayout.SOUTH);
frame.add(panel);
frame.getContentPane().setBackground(Color.GREEN);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
createAndShowGui();
}
});
}
}
JPanel graphpanel = new JPanel();
graphpanel.setBackground(Color.white);
graphpanel.setPreferredSize(new Dimension(420,420));
DrawGraph drawgraph = new DrawGraph();
graphpanel.add(drawgraph);
panel.add(graphpanel,BorderLayout.CENTER);
You add your DrawGraph component to a JPanel. By default a JPanel uses a FlowLayout() which respects the preferred size of any component added to it. Your custom DrawGraph component has a preferred size of 0, so there is nothing to paint.
Every Swing component is responsible for determining its own preferred size so you need to override the getPreferredSize() method of your DrawGraph components to return its preferred size so the layout manager can do its job.
Read the section from the Swing tutorial on Custom Painting for more information and working examples.
Also, don't use setPreferredSize(). The layout manager will determine the preferred size of the panel based on the components added to it.
First things first. Make a JFrame derived class and in that class insert separately your buttonPanel which extends JPanel on the BorderLayout.SOUTH and your DrawGraph panel on the BorederLayout.Center. Don't add butttonPanel to the window you are drawing in.
I also suggest to change name from DrawGraph to GraphPanel you can do it just by clicking on any reference to the class and hitting alt+shift+r if you use Eclipse IDE.
So to conclude:
public class MainWindow extends JFrame(){
public void createGUI(){
add(graphPanel = new GraphPanel(), BorderLayout.CENTER);
add(buttonPanel = new JPanel(), BorderLayout.SOUTH);
}
}
and build your solution around that.
I am trying to get a JPanel to appear inside of another JPanel. Currently, the JPanel is in an external JFrame and loads with my other JFrame. I want the JPanel to be inside the other JPanel so the program does not open two different windows.
Here is a picture:
The small JPanel with the text logs I want inside of the main game frame. I've tried adding the panel to the panel, panel.add(othePanel). I've tried adding it the JFrame, frame.add(otherPanel). It just overwrites everything else and gives it a black background.
How can I add the panel, resize, and move it?
Edits:
That is where I want the chatbox to be.
Class code:
Left out top of class.
public static JPanel panel;
public static JTextArea textArea = new JTextArea(5, 30);
public static JTextField userInputField = new JTextField(30);
public static void write(String message) {
Chatbox.textArea.append("[Game]: " + message + "\n");
Chatbox.textArea.setCaretPosition(Chatbox.textArea.getDocument()
.getLength());
Chatbox.userInputField.setText("");
}
public Chatbox() {
panel = new JPanel();
panel.setPreferredSize(new Dimension(220, 40));
panel.setBackground(Color.BLACK);
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setPreferredSize(new Dimension(380, 100));
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
textArea.setEditable(false);
scrollPane
.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
userInputField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
String fromUser = userInputField.getText();
if (fromUser != null) {
textArea.append(Frame.username + ":" + fromUser + "\n");
textArea.setCaretPosition(textArea.getDocument()
.getLength());
userInputField.setText("");
}
}
});
panel.add(userInputField, SwingConstants.CENTER);
panel.add(scrollPane, SwingConstants.CENTER);
//JFrame frame = new JFrame();
//frame.add(panel);
//frame.setSize(400, 170);
//frame.setVisible(true);
}
Main frame class:
public Frame() {
frame.getContentPane().remove(loginPanel);
frame.repaint();
String capName = capitalizeString(Frame.username);
name = new JLabel(capName);
new EnemyHealth("enemyhealth10.png");
new Health("health10.png");
new LoadRedCharacter("goingdown.gif");
new Spellbook();
new LoadMobs();
new LoadItems();
new Background();
new Inventory();
new ChatboxInterface();
frame.setBackground(Color.black);
Frame.redHealthLabel.setFont(new Font("Serif", Font.PLAIN, 20));
ticks.setFont(new Font("Serif", Font.PLAIN, 20));
ticks.setForeground(Color.yellow);
Frame.redHealthLabel.setForeground(Color.black);
// Inventory slots
panel.add(slot1);
panel.add(name);
name.setFont(new Font("Serif", Font.PLAIN, 20));
name.setForeground(Color.white);
panel.add(enemyHealthLabel);
panel.add(redHealthLabel);
panel.add(fireSpellBookLabel);
panel.add(iceSpellBookLabel);
panel.add(spiderLabel);
panel.add(appleLabel);
panel.add(fireMagicLabel);
panel.add(swordLabel);
// Character
panel.add(redCharacterLabel);
// Interface
panel.add(inventoryLabel);
panel.add(chatboxLabel);
// Background
panel.add(backgroundLabel);
frame.setContentPane(panel);
frame.getContentPane().invalidate();
frame.getContentPane().validate();
frame.getContentPane().repaint();
//I WOULD LIKE THE LOADING OF THE PANEL SOMEWHERE IN THIS CONSTRUCTOR.
new ResetEntities();
frame.repaint();
panel.setLayout(null);
Run.loadKeyListener();
Player.px = Connect.x;
Player.py = Connect.y;
new Mouse();
TextualMenu.rect = new Rectangle(Frame.inventoryLabel.getX() + 80,
Frame.inventoryLabel.getY() + 100,
Frame.inventoryLabel.getWidth(),
Frame.inventoryLabel.getHeight());
Player.startMessage();
}
Don't use static variables.
Don't use a null layout.
Use appropriate layout managers. Maybe the main panel uses a BorderLayout. Then you add your main component to the CENTER and a second panel to the EAST. The second panel can also use a BorderLayout. You can then add the two components to the NORTH, CENTER or SOUTH as you require.
For example, using a custom Border:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.RadialGradientPaint;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.AbstractBorder;
#SuppressWarnings("serial")
public class FrameEg extends JPanel {
public static final String FRAME_URL_PATH = "http://th02.deviantart.net/"
+ "fs70/PRE/i/2010/199/1/0/Just_Frames_5_by_ScrapBee.png";
public static final int INSET_GAP = 120;
private BufferedImage frameImg;
private BufferedImage smlFrameImg;
public FrameEg() {
try {
URL frameUrl = new URL(FRAME_URL_PATH);
frameImg = ImageIO.read(frameUrl);
final int smlFrameWidth = frameImg.getWidth() / 2;
final int smlFrameHeight = frameImg.getHeight() / 2;
smlFrameImg = new BufferedImage(smlFrameWidth, smlFrameHeight,
BufferedImage.TYPE_INT_ARGB);
Graphics g = smlFrameImg.getGraphics();
g.drawImage(frameImg, 0, 0, smlFrameWidth, smlFrameHeight, null);
g.dispose();
int top = INSET_GAP;
int left = top;
int bottom = top;
int right = left;
Insets insets = new Insets(top, left, bottom, right);
MyBorder myBorder = new MyBorder(frameImg, insets);
JTextArea textArea = new JTextArea(50, 60);
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);
for (int i = 0; i < 300; i++) {
textArea.append("Hello world! How is it going? ");
}
setLayout(new BorderLayout(1, 1));
setBackground(Color.black);
Dimension prefSize = new Dimension(frameImg.getWidth(),
frameImg.getHeight());
JPanel centerPanel = new MyPanel(prefSize);
centerPanel.setBorder(myBorder);
centerPanel.setLayout(new BorderLayout(1, 1));
centerPanel.add(new JScrollPane(textArea), BorderLayout.CENTER);
MyPanel rightUpperPanel = new MyPanel(new Dimension(smlFrameWidth,
smlFrameHeight));
MyPanel rightLowerPanel = new MyPanel(new Dimension(smlFrameWidth,
smlFrameHeight));
top = top / 2;
left = left / 2;
bottom = bottom / 2;
right = right / 2;
Insets smlInsets = new Insets(top, left, bottom, right);
rightUpperPanel.setBorder(new MyBorder(smlFrameImg, smlInsets));
rightUpperPanel.setLayout(new BorderLayout());
rightLowerPanel.setBorder(new MyBorder(smlFrameImg, smlInsets));
rightLowerPanel.setBackgroundImg(createBackgroundImg(rightLowerPanel
.getPreferredSize()));
JTextArea ruTextArea1 = new JTextArea(textArea.getDocument());
ruTextArea1.setWrapStyleWord(true);
ruTextArea1.setLineWrap(true);
rightUpperPanel.add(new JScrollPane(ruTextArea1), BorderLayout.CENTER);
JPanel rightPanel = new JPanel(new GridLayout(0, 1, 1, 1));
rightPanel.add(rightUpperPanel);
rightPanel.add(rightLowerPanel);
rightPanel.setOpaque(false);
add(centerPanel, BorderLayout.CENTER);
add(rightPanel, BorderLayout.EAST);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private BufferedImage createBackgroundImg(Dimension preferredSize) {
BufferedImage img = new BufferedImage(preferredSize.width,
preferredSize.height, BufferedImage.TYPE_INT_ARGB);
Point2D center = new Point2D.Float(img.getWidth()/2, img.getHeight()/2);
float radius = img.getWidth() / 2;
float[] dist = {0.0f, 1.0f};
Color centerColor = new Color(100, 100, 50);
Color outerColor = new Color(25, 25, 0);
Color[] colors = {centerColor , outerColor };
RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors);
Graphics2D g2 = img.createGraphics();
g2.setPaint(paint);
g2.fillRect(0, 0, img.getWidth(), img.getHeight());
g2.dispose();
return img;
}
private static void createAndShowGui() {
FrameEg mainPanel = new FrameEg();
JFrame frame = new JFrame("FrameEg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.setResizable(false);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
#SuppressWarnings("serial")
class MyPanel extends JPanel {
private Dimension prefSize;
private BufferedImage backgroundImg;
public MyPanel(Dimension prefSize) {
this.prefSize = prefSize;
}
public void setBackgroundImg(BufferedImage background) {
this.backgroundImg = background;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (backgroundImg != null) {
g.drawImage(backgroundImg, 0, 0, this);
}
}
#Override
public Dimension getPreferredSize() {
return prefSize;
}
}
#SuppressWarnings("serial")
class MyBorder extends AbstractBorder {
private BufferedImage borderImg;
private Insets insets;
public MyBorder(BufferedImage borderImg, Insets insets) {
this.borderImg = borderImg;
this.insets = insets;
}
#Override
public void paintBorder(Component c, Graphics g, int x, int y, int width,
int height) {
g.drawImage(borderImg, 0, 0, c);
}
#Override
public Insets getBorderInsets(Component c) {
return insets;
}
}
Which would look like:
I'm having trouble getting my JMenuBar to appear alongside my paint() method.
package Main;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
public class Main extends JFrame{
int x, y; // axis position for oval
//JMenuBar Variables
JMenuBar menuBar;
JMenu file;
JMenuItem newGame;
JMenuItem checkScore;
JMenuItem exitGame;
// DOUBLE BUFFERING
private Image dbImage;
private Graphics dbGraphics;
Font font = new Font("Arial", Font.ITALIC, 30);
// KeyListener Class
public class KeyListener extends KeyAdapter {
public void keyPressed(KeyEvent e){
int keyCode = e.getKeyCode();
if(keyCode == e.VK_LEFT){
if(x <=0){ // FRAME COLLISION DETECTION
x=0;
}else
x += -5; //decrement position to the left
}
if(keyCode == e.VK_RIGHT){
if(x >= 380){
x = 380;
}else
x += +5; //incrementing position to the right
}
if(keyCode == e.VK_UP){
if (y <= 25){
y = 25;
}else
y += -5; //decrementing position up
}
if(keyCode == e.VK_DOWN){
if(y >= 380){
y = 380;
}else
y += +5; //incrementing position down
}
}
}
// CONSTRUCTOR
public Main(){
// Window Properties
addKeyListener(new KeyListener()); // creates instance of KeyListener class
setTitle("Tower Defence");
setSize(400, 400);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//setBackground(Color.CYAN);
// JMenuBar
menuBar = new JMenuBar();
file = new JMenu("File");
newGame = new JMenuItem("New Game");
checkScore = new JMenuItem("Check High Scores");
exitGame = new JMenuItem("Close Game");
menuBar.add(file);
file.add(newGame);
file.add(checkScore);
file.addSeparator();
file.add(exitGame);
setJMenuBar(menuBar);
// Display frame after all components added
setVisible(true);
// default position for oval
x = 150;
y = 150;
}
public void paint(Graphics g){
dbImage = createImage(getWidth(), getHeight()); // creates image of screen
dbGraphics = dbImage.getGraphics(); // gets graphics to be drawn in off screen image
paintComponent(dbGraphics); // paints graphics
g.drawImage(dbImage, 0, 0, this); // draw image to the visible screen
}
// PAINT GRAPHICS TO SCREEN
public void paintComponent(Graphics g){
g.setFont(font);
g.drawString("Hello World", 100, 200);
g.setColor(Color.red);
g.drawOval(x, y, 15, 15);
g.fillOval(x, y, 15, 15);
repaint();
}
// MAIN METHOD
public static void main(String[] args) {
new Main();
}
}
I saw a different question where the solution was to override the paint method and add super.paint(g);
when i tried this the JMenuBar appears but the frame keeps flickering constantly.
Heck, I'll throw my code in the ring. Recs as per my comments. Also, don't use KeyListeners but rather Key Bindings.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.RenderingHints;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class Main2 extends JPanel {
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
private static final int OVAL_W = 15;
private int x = 150;
private int y = 150;
private JMenuBar menuBar;
private JMenu file;
private JMenuItem newGame;
private JMenuItem checkScore;
private JMenuItem exitGame;
private Font font = new Font("Arial", Font.ITALIC, 30);
public Main2() {
menuBar = new JMenuBar();
file = new JMenu("File");
newGame = new JMenuItem("New Game");
checkScore = new JMenuItem("Check High Scores");
exitGame = new JMenuItem("Close Game");
menuBar.add(file);
file.add(newGame);
file.add(checkScore);
file.addSeparator();
file.add(exitGame);
addKeyBinding();
}
public JMenuBar getMenuBar() {
return menuBar;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g.setFont(font);
g.drawString("Hello World", 100, 200);
g.setColor(Color.red);
g.drawOval(x, y, OVAL_W, OVAL_W);
g.fillOval(x, y, OVAL_W, OVAL_W);
}
private void addKeyBinding() {
int condition = WHEN_IN_FOCUSED_WINDOW;
InputMap inputMap = getInputMap(condition);
ActionMap actionMap = getActionMap();
for (final MyDirection dir : MyDirection.values()) {
KeyStroke keyStroke = KeyStroke.getKeyStroke(dir.getKeyCode(), 0);
inputMap.put(keyStroke, dir.toString());
actionMap.put(dir.toString(), new AbstractAction() {
#Override
public void actionPerformed(ActionEvent evt) {
int newX = x + dir.getxTrans();
int newY = y + dir.getyTrans();
newX = Math.min(newX, PREF_W - 2 * OVAL_W);
newX = Math.max(newX, OVAL_W);
newY = Math.min(newY, PREF_H - 2 * OVAL_W);
newY = Math.max(newY, OVAL_W);
x = newX;
y = newY;
repaint();
}
});
}
}
enum MyDirection {
UP(KeyEvent.VK_UP, 0, -5), DOWN(KeyEvent.VK_DOWN, 0, 5),
LEFT(KeyEvent.VK_LEFT, -5, 0), RIGHT(KeyEvent.VK_RIGHT, 5, 0);
private int keyCode;
private int xTrans;
private int yTrans;
private MyDirection(int keyCode, int xTrans, int yTrans) {
this.keyCode = keyCode;
this.xTrans = xTrans;
this.yTrans = yTrans;
}
public int getKeyCode() {
return keyCode;
}
public int getxTrans() {
return xTrans;
}
public int getyTrans() {
return yTrans;
}
}
private static void createAndShowGui() {
Main2 main = new Main2();
JFrame frame = new JFrame("Main2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(main);
frame.setJMenuBar(main.getMenuBar());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Dont extend JFrame unnecessarily
Dont overide any paint method of JFrame unnecessarily rathe add Jpanel and override paintComponent
Dont call repaint(...) in paintComponent(...) as this will cause a loop i.e repaint will re-call paintComponent and the cycle will carry on
Create and manipulate Swing components on Event Dispatch Thread
Dont call setSize(..) on JFrame rather override getPreferredSize and return an appropriate size which fits all drawings and than call JFrame#pack() before setting JFrame visible
Dont use KeyListener/KeyAdapter for Swing components rather use KeyBindings
Here is your code fixed:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
public class Main extends JPanel {
int x, y; // axis position for oval
//JMenuBar Variables
JMenuBar menuBar;
JMenu file;
JMenuItem newGame;
JMenuItem checkScore;
JMenuItem exitGame;
Font font = new Font("Arial", Font.ITALIC, 30);
// KeyBindings Class
public class KeyBindings {
public KeyBindings(final JComponent jc) {
jc.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "Right");
jc.getActionMap().put("Right", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
if (x >= 380) {
x = 380;
} else {
x += +5; //incrementing position to the right
}
jc.repaint();
}
});
jc.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "Left");
jc.getActionMap().put("Left", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
if (x <= 0) { // FRAME COLLISION DETECTION
x = 0;
} else {
x += -5; //decrement position to the left
}
jc.repaint();
}
});
jc.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "Up");
jc.getActionMap().put("Up", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
if (y <= 25) {
y = 25;
} else {
y += -5; //decrementing position up
}
jc.repaint();
}
});
jc.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "Down");
jc.getActionMap().put("Down", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
if (y >= 380) {
y = 380;
} else {
y += +5; //incrementing position down
}
jc.repaint();
}
});
}
}
// CONSTRUCTOR
public Main() {
// Window Properties
JFrame frame = new JFrame();
frame.setTitle("Tower Defence");
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//setBackground(Color.CYAN);
// JMenuBar
menuBar = new JMenuBar();
file = new JMenu("File");
newGame = new JMenuItem("New Game");
checkScore = new JMenuItem("Check High Scores");
exitGame = new JMenuItem("Close Game");
menuBar.add(file);
file.add(newGame);
file.add(checkScore);
file.addSeparator();
file.add(exitGame);
JPanel panel = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g.setFont(font);
g.drawString("Hello World", 100, 200);
g.setColor(Color.red);
g.drawOval(x, y, 15, 15);
g.fillOval(x, y, 15, 15);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
};
//add keybindings
new KeyBindings(panel);
frame.add(panel);
frame.setJMenuBar(menuBar);
frame.pack();
// Display frame after all components added
frame.setVisible(true);
// default position for oval
x = 150;
y = 150;
}
// MAIN METHOD
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Main();
}
});
}
}