JPanel Inside Of A JPanel - java

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:

Related

How to create this grid-like layout with column and row labels?

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
public class BattleShip {
private static ImageIcon image1 = new ImageIcon("cols.png");
private static ImageIcon image2 = new ImageIcon("rows.png");
private static JMenuBar menubar = new JMenuBar();
private static JPanel container = new JPanel();
private static JButton[][] button = new JButton[10][10];
private static JFrame frame = new JFrame("BattleShip");
private static JButton open;
public static void fileMenu() {
JMenu fileMenu = new JMenu("File");
JMenuItem open = new JMenuItem("Open");
open.setMnemonic(KeyEvent.VK_O);
open.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, KeyEvent.CTRL_MASK));
JMenuItem restartGame = new JMenuItem("Restart Game");
restartGame.setMnemonic(KeyEvent.VK_R);
restartGame.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, KeyEvent.CTRL_MASK));
JMenuItem exit = new JMenuItem("Exit");
exit.setMnemonic(KeyEvent.VK_E);
exit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, KeyEvent.CTRL_MASK));
open.addActionListener(new OpenMenu());
exit.addActionListener(new ExitMenu());
fileMenu.add(open);
fileMenu.add(restartGame);
fileMenu.add(exit);
menubar.add(fileMenu);
}
public static void layout() {
JPanel panelOne = new JPanel();
JPanel panelTwo = new JPanel();
JPanel playerPanel = new JPanel();
JPanel cpuPanel = new JPanel();
panelOne.add(playerPanel, BorderLayout.CENTER);
panelOne.setLayout(new BorderLayout());
panelTwo.setLayout(new BorderLayout());
panelOne.add(new JLabel(image1), BorderLayout.NORTH);
panelTwo.add(new JLabel(image1), BorderLayout.NORTH);
panelOne.add(new JLabel(image2), BorderLayout.WEST);
panelTwo.add(new JLabel(image2), BorderLayout.WEST);
panelOne.add(playerPanel, BorderLayout.CENTER);
container.setLayout(new GridLayout(1,2));
container.add(panelOne);
container.add(panelTwo);
}
public static void FlowLayout() {
JPanel panel = new JPanel();
JPanel panel1 = new JPanel();
JPanel playerSide = new JPanel();
panel.setLayout(new BoxLayout(panel,BoxLayout.X_AXIS));
JLabel cols = new JLabel();
cols.setIcon(image1);
JLabel rows = new JLabel();
rows.setIcon(image2);
panel.add(cols);
}
public static void main(String[] args) {
fileMenu();
layout();
frame.add(container);
frame.setJMenuBar(menubar);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setVisible(true);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private static class ExitMenu implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
private static class OpenMenu implements ActionListener {
public void actionPerformed(ActionEvent e) {
}
}
private static class SelectFile implements ActionListener {
public void actionPerformed(ActionEvent event) {
if (event.getSource() == open) {
}
}
}
}
How can I do this layout with the rows and cols as a picture?
For the cols how would i do the white space and combine the two together and make a grid? None of the other questions shows me how to do this layout?
[![enter image description here][1]][1]
Shoot, I made something just like that that I'll try to dig out....
Made a long while ago and used two jpg images to create a GUI like so:
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class BattleShipMainProg {
private static void createAndShowGui() {
BattleShipMainPanel mainPanel;
try {
mainPanel = new BattleShipMainPanel();
JFrame frame = new JFrame("Battleship");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
#SuppressWarnings("serial")
public class BattleShipMainPanel extends JPanel {
private static final int TA_ROWS = 10;
private static final int TA_COLS = 30;
private static final int CELL_SIDE_LENGTH = 36;
private static final String WEST_IMG_PATH = "battleship/images/Wallpaper-Picture-Under-Water Crp.jpg";
private static final String EAST_IMG_PATH = "battleship/images/Maldives_Sml.jpg";
private BattleShipGridPanel playerGrid;
private BattleShipGridPanel opponentGrid;
private ShipImageMaker imageMaker = new ShipImageMaker(CELL_SIDE_LENGTH);
private JTextArea textarea = new JTextArea(TA_ROWS, TA_COLS);
public BattleShipMainPanel() throws IOException {
ClassLoader classLoader = getClass().getClassLoader();
System.out.println(classLoader.getResource("").getFile());
String westImgString = WEST_IMG_PATH;
String eastImgString = EAST_IMG_PATH;
BufferedImage westImg = ImageIO.read(getClass().getClassLoader()
.getResource(westImgString));
BufferedImage eastImg = ImageIO.read(getClass().getClassLoader()
.getResource(eastImgString));
playerGrid = new BattleShipGridPanel(westImg, CELL_SIDE_LENGTH);
opponentGrid = new BattleShipGridPanel(eastImg, CELL_SIDE_LENGTH);
// !! to delete
playerGrid.getLabel("A 1").setIcon(imageMaker.getSternLeftIcon()[0]);
playerGrid.getLabel("A 2").setIcon(imageMaker.getMidshipHorizIcon()[0]);
playerGrid.getLabel("A 3").setIcon(imageMaker.getMidshipHorizIcon()[0]);
playerGrid.getLabel("A 4").setIcon(imageMaker.getMidshipHorizIcon()[0]);
playerGrid.getLabel("A 5").setIcon(imageMaker.getBowRightIcon()[0]);
playerGrid.getLabel("C 2").setIcon(imageMaker.getBowUpIcon()[1]);
playerGrid.getLabel("D 2").setIcon(imageMaker.getMidshipVertIcon()[1]);
playerGrid.getLabel("E 2").setIcon(imageMaker.getSternDownIcon()[1]);
// !! to delete
playerGrid.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent pChngEvt) {
if (pChngEvt.getPropertyName().equals(
BattleShipGridPanel.MOUSE_PRESSED)) {
textarea.append("Player: " + pChngEvt.getNewValue() + "\n");
System.out.printf("[%c, %d]%n", playerGrid.getSelectedRow(), playerGrid.getSelectedCol());
playerGrid.resetSelections();
}
}
});
opponentGrid.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent pChngEvt) {
if (pChngEvt.getPropertyName().equals(
BattleShipGridPanel.MOUSE_PRESSED)) {
textarea.append("Opponent: " + pChngEvt.getNewValue() + "\n");
opponentGrid.resetSelections();
}
}
});
textarea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12));
textarea.setEditable(false);
textarea.setFocusable(false);
JPanel centerPanel = new JPanel();
centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.PAGE_AXIS));
JPanel centerTopPanel = new JPanel(new BorderLayout());
centerTopPanel.add(new JLabel("GridCell Pressed", SwingConstants.LEFT),
BorderLayout.NORTH);
centerTopPanel.add(new JScrollPane(textarea,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER));
centerPanel.add(centerTopPanel);
centerPanel.add(Box.createVerticalGlue());
JPanel playerPanel = new JPanel(new BorderLayout());
playerPanel.add(new JLabel("Player", JLabel.LEFT),
BorderLayout.PAGE_START);
playerPanel.add(playerGrid.getMainPanel(), BorderLayout.CENTER);
JPanel opponentPanel = new JPanel(new BorderLayout());
opponentPanel.add(new JLabel("Opponent", JLabel.LEFT),
BorderLayout.PAGE_START);
opponentPanel.add(opponentGrid.getMainPanel(), BorderLayout.CENTER);
int eb = 10;
setBorder(BorderFactory.createEmptyBorder(eb, eb, eb, eb));
setLayout(new BorderLayout(eb, eb));
add(playerPanel, BorderLayout.WEST);
add(opponentPanel, BorderLayout.EAST);
add(centerPanel, BorderLayout.CENTER);
}
}
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.SwingPropertyChangeSupport;
#SuppressWarnings("serial")
public class BattleShipGridPanel {
public static final String MOUSE_PRESSED = "Mouse Pressed";
// public static final String MOUSE_DRAGGED = "Mouse Dragged";
private static final int ROW_COUNT = 11;
private static final int COL_COUNT = 11;
// the main JPanel for this part of my program
private JPanel mainPanel = new JPanel(){
// it draws an image if available
protected void paintComponent(Graphics g) {
super.paintComponent(g);
myPaint(g);
};
};
private Image img = null;
private String selectedCellName = "";
private JLabel selectedLabel = null;
private Map<String, JLabel> labelMap = new HashMap<String, JLabel>();
private SwingPropertyChangeSupport propChangeSupport = new SwingPropertyChangeSupport(this);
public BattleShipGridPanel(Image img, int cellSideLength) {
this.img = img;
mainPanel.setLayout(new GridLayout(11, 11));
mainPanel.setBorder(BorderFactory.createLineBorder(Color.black));
MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
mainPanel.addMouseListener(myMouseAdapter);
for (int row = 0; row < ROW_COUNT; row++) {
for (int col = 0; col < COL_COUNT; col++) {
String rowStr = String.valueOf((char) ('A' + row - 1));
String colStr = String.valueOf(col);
String name = ""; // name for component
String text = ""; // text to display
// create JLabel to add to grid
JLabel label = new JLabel("", SwingConstants.CENTER);
// text to display if label is a row header at col 0
if (col == 0 && row != 0) {
text = "" + rowStr;
} else
// text to display if label is a col header at row 0
if (row == 0 && col != 0) {
text = "" + colStr;
} else
// name to give to label if label is on the grid and not a
// row or col header
if (row != 0 && col != 0) {
name = rowStr + " " + colStr;
labelMap.put(name, label);
}
label.setText(text);
label.setName(name);
label.setPreferredSize(new Dimension(cellSideLength, cellSideLength));
label.setBorder(BorderFactory.createLineBorder(Color.black));
mainPanel.add(label);
}
}
}
private void myPaint(Graphics g) {
if (img != null) {
int w0 = mainPanel.getWidth();
int h0 = mainPanel.getHeight();
int x = w0 / 11;
int y = h0 / 11;
int iW = img.getWidth(null);
int iH = img.getHeight(null);
g.drawImage(img, x, y, w0, h0, 0, 0, iW, iH, null);
}
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
propChangeSupport.addPropertyChangeListener(listener);
}
private class MyMouseAdapter extends MouseAdapter {
#Override
public void mousePressed(MouseEvent mEvt) {
if (mEvt.getButton() == MouseEvent.BUTTON1) {
Component comp = mainPanel.getComponentAt(mEvt.getPoint());
if (comp instanceof JLabel) {
String name = comp.getName();
if (!name.trim().isEmpty()) {
String oldValue = selectedCellName;
String newValue = name;
selectedCellName = name;
selectedLabel = (JLabel) comp;
propChangeSupport.firePropertyChange(MOUSE_PRESSED, oldValue, newValue);
}
}
}
}
}
public JPanel getMainPanel() {
return mainPanel;
}
public String getSelectedCellName() {
return selectedCellName;
}
public char getSelectedRow() {
if (selectedCellName.isEmpty()) {
return (char)0;
} else {
return selectedCellName.split(" ")[0].charAt(0);
}
}
public int getSelectedCol() {
if (selectedCellName.isEmpty()) {
return 0;
} else {
return Integer.parseInt(selectedCellName.split(" ")[1]);
}
}
public JLabel getSelectedLabel() {
return selectedLabel;
}
public void resetSelections() {
selectedCellName = "";
selectedLabel = null;
}
public JLabel getLabel(String key) {
return labelMap.get(key);
}
public void resetAll() {
resetSelections();
for (String key : labelMap.keySet()) {
labelMap.get(key).setIcon(null);
}
}
// for testing purposes only
private static void createAndShowGui() {
// path to some undersea image
String imgPath = "http://upload.wikimedia.org/wikipedia/"
+ "commons/3/31/Great_white_shark_south_africa.jpg";
BufferedImage img = null;
try {
img = ImageIO.read(new URL(imgPath));
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
int cellSideLength = 36;
BattleShipGridPanel gridPanel = new BattleShipGridPanel(img, cellSideLength);
gridPanel.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
// print out where the mouse pressed:
System.out.println(evt.getNewValue());
}
});
JFrame frame = new JFrame("BattleShipGridPanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(gridPanel.getMainPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.geom.CubicCurve2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.Path2D.Double;
import java.awt.geom.QuadCurve2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class ShipImageMaker {
public static final double GAP = 1.0 / 10.0;
public static final Color LINE_COLOR = Color.black;
public static final Color[] SHIP_FILL_COLOR = { // Color.LIGHT_GRAY,
new Color(200, 200, 200, 180),
new Color(255, 100, 100, 180) };
public static final Color SHIP_BACKGROUND_COLOR = new Color(0, 0, 0, 0);
private AffineTransform rotateUp;
private ImageIcon[] bowRightIcon = new ImageIcon[2];
private ImageIcon[] bowUpIcon = new ImageIcon[2];
private ImageIcon[] sternLeftIcon = new ImageIcon[2];
private ImageIcon[] sternDownIcon = new ImageIcon[2];
private ImageIcon[] midshipHorizIcon = new ImageIcon[2];
private ImageIcon[] midshipVertIcon = new ImageIcon[2];
public ShipImageMaker(int side) {
rotateUp = AffineTransform.getQuadrantRotateInstance(3, side / 2,
side / 2);
Path2D turretPath = new Path2D.Double();
double tpX = side / 2.0 - 3 * GAP * side;
double tpY = side / 2.0 - 1.5 * GAP * side;
double tpW = 3 * GAP * side;
double tpH = tpW;
double lx1 = tpX + tpW;
double ly1 = side / 2.0 - 0.5 * GAP * side;
double lx2 = lx1 + 1.5 * GAP * side;
double ly2 = ly1;
turretPath.append(new Ellipse2D.Double(tpX, tpY, tpW, tpH), false);
turretPath.append(new Line2D.Double(lx1, ly1, lx2, ly2), false);
turretPath.append(new Line2D.Double(lx1, side - ly1, lx2, side - ly2),
false);
double y1 = GAP * side;
double ctrlx = side / 2.0;
double ctrly = y1;
double x2 = side - y1;
double y2 = side / 2.0;
QuadCurve2D topQC = new QuadCurve2D.Double(0, y1, ctrlx, ctrly, x2, y2);
QuadCurve2D botQC = new QuadCurve2D.Double(x2, y2, ctrlx, side - ctrly,
0, side - y1);
Path2D bowFillPath = new Path2D.Double();
bowFillPath.moveTo(0, y1);
bowFillPath.append(topQC, false);
bowFillPath.append(botQC, false);
bowFillPath.lineTo(0, y1);
Path2D bowDrawPath = new Path2D.Double();
bowDrawPath.append(topQC, false);
bowDrawPath.append(botQC, false);
bowDrawPath.append(turretPath, false);
Line2D midShipTopLine = new Line2D.Double(0, y1, side, y1);
Line2D midShipBotLine = new Line2D.Double(side, side - y1, 0, side - y1);
Path2D midShipFillPath = new Path2D.Double();
midShipFillPath.moveTo(0, y1);
midShipFillPath.append(midShipTopLine, false);
midShipFillPath.lineTo(side, side - y1);
midShipFillPath.append(midShipBotLine, false);
midShipFillPath.lineTo(0, y1);
Path2D midShipDrawPath = new Path2D.Double();
midShipDrawPath.append(midShipTopLine, false);
midShipDrawPath.append(midShipBotLine, false);
midShipDrawPath.append(turretPath, false);
Path2D sternDrawPath = new Path2D.Double();
sternDrawPath.moveTo(side, y1);
sternDrawPath.lineTo(side / 2, y1);
sternDrawPath.append(new CubicCurve2D.Double(side / 2, y1, y1, y1, y1,
side - y1, side / 2, side - y1), false);
sternDrawPath.lineTo(side, side - y1);
Path2D sternFillPath = new Path2D.Double(sternDrawPath);
sternFillPath.lineTo(side, y1);
sternDrawPath.append(turretPath.createTransformedShape(AffineTransform
.getQuadrantRotateInstance(2, side / 2, side / 2)), false);
for (int i = 0; i < bowRightIcon.length; i++) {
BufferedImage img = createImage(side, bowFillPath, bowDrawPath,
SHIP_FILL_COLOR[i]);
bowRightIcon[i] = new ImageIcon(img);
bowUpIcon[i] = rotateUp(side, img);
img = createImage(side, midShipFillPath, midShipDrawPath,
SHIP_FILL_COLOR[i]);
midshipHorizIcon[i] = new ImageIcon(img);
midshipVertIcon[i] = rotateUp(side, img);
img = createImage(side, sternFillPath, sternDrawPath,
SHIP_FILL_COLOR[i]);
sternLeftIcon[i] = new ImageIcon(img);
sternDownIcon[i] = rotateUp(side, img);
}
}
private BufferedImage createImage(int side, Path2D fillPath,
Path2D drawPath, Color shipFillColor) {
BufferedImage img = new BufferedImage(side, side,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(shipFillColor);
g2.setBackground(SHIP_BACKGROUND_COLOR);
g2.fill(fillPath);
g2.setColor(LINE_COLOR);
g2.setStroke(new BasicStroke(2f));
g2.draw(drawPath);
g2.dispose();
return img;
}
private ImageIcon rotateUp(int side, BufferedImage src) {
BufferedImage img = new BufferedImage(side, side,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
g2.setTransform(rotateUp);
g2.drawImage(src, 0, 0, null);
g2.dispose();
return new ImageIcon(img);
}
public ImageIcon[] getBowRightIcon() {
return bowRightIcon;
}
public ImageIcon[] getBowUpIcon() {
return bowUpIcon;
}
public ImageIcon[] getSternLeftIcon() {
return sternLeftIcon;
}
public ImageIcon[] getSternDownIcon() {
return sternDownIcon;
}
public ImageIcon[] getMidshipHorizIcon() {
return midshipHorizIcon;
}
public ImageIcon[] getMidshipVertIcon() {
return midshipVertIcon;
}
public static void main(String[] args) {
List<Icon> icons = new ArrayList<Icon>();
ShipImageMaker imgMaker = new ShipImageMaker(40);
icons.add(imgMaker.getBowRightIcon()[0]);
icons.add(imgMaker.getBowRightIcon()[1]);
icons.add(imgMaker.getBowUpIcon()[0]);
icons.add(imgMaker.getBowUpIcon()[1]);
icons.add(imgMaker.getMidshipHorizIcon()[0]);
icons.add(imgMaker.getMidshipHorizIcon()[1]);
icons.add(imgMaker.getMidshipVertIcon()[0]);
icons.add(imgMaker.getMidshipVertIcon()[1]);
icons.add(imgMaker.getSternDownIcon()[0]);
icons.add(imgMaker.getSternDownIcon()[1]);
icons.add(imgMaker.getSternLeftIcon()[0]);
icons.add(imgMaker.getSternLeftIcon()[1]);
for (Icon icon : icons) {
JOptionPane.showMessageDialog(null, new JLabel(icon));
}
}
}
Used BorderLayout, GridLayout and BoxLayout.
A lot will come down to what it is you want to achieve, for example you could use a GridLayout, GridBagLayout or a combination of layout managers or you could use custom painting or you could use a JTable for example...
Now, this is pretty basic and is only intended to provide a proof of concept
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
import javax.swing.border.MatteBorder;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new MainPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class MainPane extends JPanel {
public MainPane() {
setLayout(new BorderLayout());
DefaultTableModel model = new DefaultTableModel(10, 10);
JTable table = new JTable(model);
table.setRowHeight(40);
table.setShowGrid(true);
table.setGridColor(Color.BLACK);
JScrollPane sp = new JScrollPane(table);
sp.setRowHeaderView(new RowHeader(table));
add(sp);
}
}
public class RowHeader extends JPanel {
private JTable table;
public RowHeader(JTable table) {
setOpaque(false);
this.table = table;
table.getModel().addTableModelListener(new TableModelListener() {
#Override
public void tableChanged(TableModelEvent e) {
prepareLayout();
}
});
setLayout(new GridBagLayout());
prepareLayout();
}
protected void prepareLayout() {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.CENTER;
Border border = new MatteBorder(0, 1, 1, 1, Color.BLACK);
for (int row = 0; row < 10; row++) {
char value = (char) ('A' + row);
JLabel label = makeLabel(Character.toString(value));
label.setBorder(border);
add(label, gbc);
}
gbc.weighty = 1;
JLabel filler = makeLabel("");
filler.setBorder(new MatteBorder(1, 0, 0, 0, Color.BLACK));
add(filler, gbc);
}
protected JLabel makeLabel(String text) {
JLabel label = new JLabel(text) {
#Override
public Dimension getPreferredSize() {
Dimension size = super.getPreferredSize();
size.height = table.getRowHeight();
size.width += 10;
return size;
}
};
label.setHorizontalAlignment(JLabel.CENTER);
return label;
}
}
}
Use BorderLayout, take 3 panel and set them in NORTH, CENTER and SOUTH. IN CENTER use JTable. to diaplay your table and if you want to add the alphabet also between two tables you can split your center panel by adding sub panels in the center panel.
like center_panel.add(subpanel1, and your desire location), or simply go through flow layout.

How centrate JLabel in a GridLayout [duplicate]

I'm making a score-keeping program, but I'm running into a problem. What I've tried to do is have a JPanel at the top that contains two JPanels, which, in turn, contains two team names. I'm confused as to why the two JLabels at the top of the program aren't centered inside of the JPanels they're contained in.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ScoreFrame extends JFrame {
private static final Dimension SCREEN_SIZE = Toolkit.getDefaultToolkit().getScreenSize();
private static final int WIDTH = SCREEN_SIZE.width;
private static final int HEIGHT = SCREEN_SIZE.height;
private final JTextField[] nameField = new JTextField[] { new JTextField(), new JTextField() };
private final JLabel[] nameLabel = new JLabel[] { new JLabel("Team 1"), new JLabel("Team 2") };
private final GridBagLayout gridBag = new GridBagLayout();
private final GridBagConstraints constraints = new GridBagConstraints();
private final JPanel topPanel = new JPanel();
public ScoreFrame() {
super();
setResizable(false);
setSize(SCREEN_SIZE);
setLayout(gridBag);
setUndecorated(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addKeyListener(new EscapeListener());
addComponents();
}
private void addComponents() {
addToTopPanel();
constraints.insets = new Insets(0, 0, (int) (HEIGHT * (double) 4 / 5), 0);
gridBag.setConstraints(topPanel, constraints);
add(topPanel);
}
private void addToTopPanel() {
final JPanel[] teamPanel = new JPanel[] { new JPanel(), new JPanel() };
topPanel.setLayout(gridBag);
topPanel.setSize(new Dimension(WIDTH, HEIGHT / 5));
Dimension teamPanelSize = new Dimension(WIDTH / 2, HEIGHT / 5);
teamPanel[0].setSize(teamPanelSize);
teamPanel[1].setSize(teamPanelSize);
Font nameFont = new Font("Times New Roman", Font.PLAIN, 50);
nameLabel[0].setFont(nameFont);
nameLabel[1].setFont(nameFont);
teamPanel[0].add(nameLabel[0]);
teamPanel[1].add(nameLabel[1]);
gridBag.setConstraints(teamPanel[0], constraints);
constraints.gridx = 1;
gridBag.setConstraints(teamPanel[1], constraints);
topPanel.add(teamPanel[0]);
topPanel.add(teamPanel[1]);
}
public void paint(Graphics g) {
super.paint(g);
int strokeSize = ((WIDTH + HEIGHT) / 2) / 300;
if (strokeSize < 1) {
strokeSize = 1;
}
final int fontSize = (int) (strokeSize * 12.5);
Graphics2D g2d = (Graphics2D) g;
g2d.setStroke(new BasicStroke(strokeSize));
g.drawLine(WIDTH / 2, 0, WIDTH / 2, HEIGHT / 5);
g.drawLine(WIDTH / 2, (int) (HEIGHT * (double) 105 / 400), WIDTH / 2, HEIGHT);
g.drawLine(0, HEIGHT / 5, WIDTH, HEIGHT / 5);
g.drawRect((int) (WIDTH * (double) 45 / 100), HEIGHT / 5, WIDTH / 10, (int) (HEIGHT * (double) 3 / 20));
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g.setFont(new Font("Times New Roman", Font.PLAIN, fontSize));
g.drawString("Errors", (int) (WIDTH * (double) 101 / 220), HEIGHT / 4);
}
private JFrame getFrame() {
return this;
}
public static void main(final String args[]) {
new ScoreFrame().setVisible(true);
}
public class EscapeListener implements KeyListener {
public void keyPressed(final KeyEvent event) {
if (event.getKeyCode() == 27) {
final int choice = JOptionPane.showConfirmDialog(getFrame(), "Do you want to exit the program?");
if (choice == 0) {
System.exit(0);
}
}
}
public void keyReleased(final KeyEvent event) {
}
public void keyTyped(final KeyEvent event) {
}
}
}
Invoking pack() is a critical step in using layouts. This example uses JLabel.CENTER and GridLayout to center the labels equally as the frame is resized. For simplicity, the center panel is simply a placeholder. This somewhat more complex example uses a similar approach along with java.text.MessageFormat.
Addendum: But how would I apply pack() to my code?
Simply invoke pack() as shown in the examples cited. I don't see an easy way to salvage your current approach of setting sizes extrinsically. Instead, override getPreferredSize() in a JPanel for your main content. No matter the screen size, your implementation of paintComponent() should adapt to the current size, for example.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
/** #see https://stackoverflow.com/a/14422016/230513 */
public class Scores {
private final JLabel[] nameLabel = new JLabel[]{
new JLabel("Team 1", JLabel.CENTER),
new JLabel("Team 2", JLabel.CENTER)};
private void display() {
JFrame f = new JFrame("Scores");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel teamPanel = new JPanel(new GridLayout(1, 0));
teamPanel.add(nameLabel[0]);
teamPanel.add(nameLabel[1]);
f.add(teamPanel, BorderLayout.NORTH);
f.add(new JPanel() {
#Override
public Dimension getPreferredSize() {
return new Dimension(320, 240);
}
}, BorderLayout.CENTER);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Scores().display();
}
});
}
}

Custom Swing Component Model, Component, UI delegate

I am very new to java in general and especially using Swing. I have created a custom swing component that zooms in and out on a picture using a slider. However I am now required to make it so that my code represents three classes
• Model
• The UI delegate
• An implementation of the component to bundle the model and UI delegate
together
I am very lost and cannot seem to get the code to function properly when I begin splitting it up into different classes. I have the interface working when implemented in a single class. Any help on how best to retool this code so that it fits into the previously mentioned model would be greatly appreciated. Here is my code.
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.*;
import java.io.File;
import java.net.URL;
import javax.imageio.ImageIO;
public class CustomComponent extends JComponent implements ChangeListener {
JPanel gui;
JLabel imageCanvas;
Dimension size;
double scale = 1.0;
private BufferedImage image;
public CustomComponent() {
size = new Dimension(10, 10);
setBackground(Color.black);
try {
image = ImageIO.read(new File("car.jpg"));
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void setImage(Image image) {
imageCanvas.setIcon(new ImageIcon(image));
}
public void initComponents() {
if (gui == null) {
gui = new JPanel(new BorderLayout());
gui.setBorder(new EmptyBorder(5, 5, 5, 5));
imageCanvas = new JLabel();
JPanel imageCenter = new JPanel(new GridBagLayout());
imageCenter.add(imageCanvas);
JScrollPane imageScroll = new JScrollPane(imageCenter);
imageScroll.setPreferredSize(new Dimension(300, 100));
gui.add(imageScroll, BorderLayout.CENTER);
}
}
public Container getGui() {
initComponents();
return gui;
}
public void stateChanged(ChangeEvent e) {
int value = ((JSlider) e.getSource()).getValue();
scale = value / 100.0;
paintImage();
}
protected void paintImage() {
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
BufferedImage bi = new BufferedImage(
(int)(imageWidth*scale),
(int)(imageHeight*scale),
image.getType());
Graphics2D g2 = bi.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
AffineTransform at = AffineTransform.getTranslateInstance(0, 0);
at.scale(scale, scale);
g2.drawRenderedImage(image, at);
setImage(bi);
}
public Dimension getPreferredSize() {
int w = (int) (scale * size.width);
int h = (int) (scale * size.height);
return new Dimension(w, h);
}
private JSlider getControl() {
JSlider slider = new JSlider(JSlider.HORIZONTAL, 1, 500, 50);
slider.setMajorTickSpacing(50);
slider.setMinorTickSpacing(25);
slider.setPaintTicks(true);
slider.setPaintLabels(true);
slider.addChangeListener(this);
return slider;
}
public static void main(String[] args) {
CustomComponent app = new CustomComponent();
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(app.getGui());
app.setImage(app.image);
// frame.getContentPane().add(new JScrollPane(app));
frame.getContentPane().add(app.getControl(), "Last");
frame.setSize(700, 500);
frame.setLocation(200, 200);
frame.setVisible(true);
}
}

Graph not showing inside JPanel

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.

Make JScrollPane control multiple components

For my application I am designing a script editor. At the moment I have a JPanel which contains another JPanel that holds the line number (positioned to the left), and a JTextArea which is used to allow users to type their code in (positioned to the right).
At the moment, I have implemented a JScrollPane on the JTextArea to allow the user to scroll through their code.
For the JPanel containing the line numbers, they increment every time the user presses the enter key.
However, the problem is that I want the same JScrollPane (the one implemented on the JTextArea) to control the scrolling of the line number JPanel as well; i.e. when the user scrolls on the JTextArea, the line number JPanel should also scroll. But since the line numbers are held in a JPanel, I cant add that component to a JTextArea.
The constructor for the JPanel class containing the JTextArea and the line number JPanel:
private ScriptEditor() {
setBackground(Color.WHITE);
lineNumPanel = new LineNumberPanel();
scriptArea = new JTextArea();
scriptArea.setLineWrap(true);
scriptArea.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 15));
scriptArea.setMargin(new Insets(3, 10, 0, 10));
JScrollPane scrollPane = new JScrollPane(scriptArea);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setPreferredSize(new Dimension(width, height));
scriptArea.addKeyListener(this);
add(lineNumPanel);
add(scrollPane);
}
The constructor for the line number JPanel which adds JLabels within itself to represent the line numbers:
public LineNumberPanel() {
setPreferredSize(new Dimension(width, height));
box = Box.createVerticalBox();
add(box);
//setup the label
label = new JLabel(String.valueOf(lineCount));
label.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 15));
//setup the label alignment
label.setVerticalAlignment(JLabel.TOP);
label.setHorizontalAlignment(JLabel.CENTER);
label.setVerticalTextPosition(JLabel.TOP);
setAlignmentY(TOP_ALIGNMENT);
box.add(label);
}
You should use JScrollPane#setRowHeaderView to set the component that will appear at the left hand side of the scroll pane.
The benefit of this is the row header won't scroll to the left as the view scrolls to the right...
The example deliberately uses line wrapping...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.Element;
import javax.swing.text.Utilities;
public class ScrollColumnHeader {
public static void main(String[] args) {
new ScrollColumnHeader();
}
public ScrollColumnHeader() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JTextArea ta = new JTextArea(20, 40);
ta.setWrapStyleWord(true);
ta.setLineWrap(true);
JScrollPane sp = new JScrollPane(ta);
sp.setRowHeaderView(new LineNumberPane(ta));
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(sp);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class LineNumberPane extends JPanel {
private JTextArea ta;
public LineNumberPane(JTextArea ta) {
this.ta = ta;
ta.getDocument().addDocumentListener(new DocumentListener() {
#Override
public void insertUpdate(DocumentEvent e) {
revalidate();
repaint();
}
#Override
public void removeUpdate(DocumentEvent e) {
revalidate();
repaint();
}
#Override
public void changedUpdate(DocumentEvent e) {
revalidate();
repaint();
}
});
}
#Override
public Dimension getPreferredSize() {
FontMetrics fm = getFontMetrics(getFont());
int lineCount = ta.getLineCount();
Insets insets = getInsets();
int min = fm.stringWidth("000");
int width = Math.max(min, fm.stringWidth(Integer.toString(lineCount))) + insets.left + insets.right;
int height = fm.getHeight() * lineCount;
return new Dimension(width, height);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
FontMetrics fm = ta.getFontMetrics(ta.getFont());
Insets insets = getInsets();
Rectangle clip = g.getClipBounds();
int rowStartOffset = ta.viewToModel(new Point(0, clip.y));
int endOffset = ta.viewToModel(new Point(0, clip.y + clip.height));
Element root = ta.getDocument().getDefaultRootElement();
while (rowStartOffset <= endOffset) {
try {
int index = root.getElementIndex(rowStartOffset);
Element line = root.getElement(index);
String lineNumber = "";
if (line.getStartOffset() == rowStartOffset) {
lineNumber = String.valueOf(index + 1);
}
int stringWidth = fm.stringWidth(lineNumber);
int x = insets.left;
Rectangle r = ta.modelToView(rowStartOffset);
int y = r.y + r.height;
g.drawString(lineNumber, x, y - fm.getDescent());
// Move to the next row
rowStartOffset = Utilities.getRowEnd(ta, rowStartOffset) + 1;
} catch (Exception e) {
break;
}
}
}
}
}
And as I just discovered, #camickr has a much more useful example, Text Component Line Number
Create an Outer Panel which holds the Line Number panel and Text Area.
Then put this new panel into the Scroll Pane so you end up with this arrangement:
Which in code is something like:
private ScriptEditor() {
setBackground(Color.WHITE);
JPanel outerPanel = new JPanel();
lineNumPanel = new LineNumberPanel();
scriptArea = new JTextArea();
scriptArea.setLineWrap(true);
scriptArea.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 15));
scriptArea.setMargin(new Insets(3, 10, 0, 10));
outerPanel.add(lineNumPanel, BorderLayout.WEST)
outerPanel.add(scriptArea, BorderLayout.CENTER)
JScrollPane scrollPane = new JScrollPane(outerPanel);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setPreferredSize(new Dimension(width, height));
scriptArea.addKeyListener(this);
add(lineNumPanel);
add(scrollPane);
}
I suggest placing both components into a panel, then place that panel into the scroll pane.

Categories

Resources