Althougt I tried as hard as I can I can't cope with my problem. The problem is this: I want to print a JComponent from my frame, to be exact a JPanel, but it is too big to fit standard A4 page either in portrait or landscape. To get this work I implemented code from here Fit/Scale JComponent to page being printed so my ComponentPrintable class looks like this:
public class ComponentPrintable extends JPanel implements Printable {
private Component comp;
public ComponentPrintable(Component comp)
{
this.comp = comp;
}
#Override
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException
{
if (pageIndex > 0) {
return Printable.NO_SUCH_PAGE;
}
Dimension componentSize = comp.getPreferredSize();
comp.setSize(componentSize);
Dimension printSize = new Dimension();
printSize.setSize(pageFormat.getImageableWidth(), pageFormat.getImageableHeight());
double scaleFactor = getScaleFactorToFit(componentSize, printSize);
if (scaleFactor > 1d) {
scaleFactor = 1d;
}
double scaleWidth = componentSize.width * scaleFactor;
double scaleHeight = componentSize.height * scaleFactor;
Graphics2D g2 = (Graphics2D)graphics;
double x = ((pageFormat.getImageableWidth() - scaleWidth)/2d) + pageFormat.getImageableX();
double y = ((pageFormat.getImageableHeight() - scaleHeight)/2d) + pageFormat.getImageableY();
AffineTransform at = new AffineTransform();
at.translate(x, y);
at.scale(scaleFactor, scaleFactor);
g2.transform(at);
comp.printAll(g2);
g2.dispose();
comp.revalidate();
return PAGE_EXISTS;
}
private double getScaleFactorToFit(Dimension original, Dimension toFit) {
double dScale = 1d;
if (original != null && toFit != null) {
double dScaleWidth = getScaleFactor(original.width, toFit.width);
double dScaleHeight = getScaleFactor(original.height, toFit.height);
dScale = Math.min(dScaleHeight, dScaleWidth);
}
return dScale;
}
private double getScaleFactor(int iMasterSize, int iTargetSize) {
double dScale = 1;
if (iMasterSize > iTargetSize) {
dScale = (double) iTargetSize / (double) iMasterSize;
}
else {
dScale = (double) iTargetSize / (double) iMasterSize;
}
return dScale;
}
}
Now I've created two GUI forms in IntelliJ GUI designer: MainWindow and TmpPanel (which has been also created in designer so it is formally a JFrame).
Those two looks like this (both XML files provided in link below)
https://www.dropbox.com/sh/lmg8xcj2cghgqzn/AADHgX6Esm30iS7r6GeVA4_0a?dl=0
Binded classes:
public class TmpPanel extends JFrame
{
private JPanel panel1;
private JPanel checkBoxPanel;
private JCheckBox fee;
private JCheckBox administration;
private JCheckBox water;
private JCheckBox booking;
private JCheckBox electricity;
private JCheckBox toilet;
private JPanel printPanel;
private JPanel dataPanel;
private JPanel generalTablePanel;
private JPanel summaryPanel;
private JLabel fakturaNr;
private JLabel CopyOriginal;
private JPanel SalePanel;
private JPanel SposobZaplatyPanel;
private JPanel NabywcaPanel;
private JPanel SprzedawcaPanel;
private JPanel servicesTablePanel;
private JPanel summaryTablePanel;
private JPanel[] panels = {panel1, checkBoxPanel, printPanel, dataPanel, generalTablePanel, summaryTablePanel, summaryPanel,
SalePanel, SposobZaplatyPanel, NabywcaPanel, SprzedawcaPanel, servicesTablePanel};
public TmpPanel()
{
for(JPanel x: panels)
{
x.repaint();
x.validate();
System.out.println(x.isValid());
}
setContentPane(panel1);
System.out.println(getContentPane().isValid());
System.out.println(printPanel.isValid());
}
public Component getPrintablePanel()
{
return printPanel;
}
}
and
public class MainWindow extends JFrame implements ActionListener
{
private JTabbedPane tabbedPane1;
private JPanel rootPanel;
private JButton printButton;
private JButton newClientButton;
private JButton removeClientButton;
public MainWindow()
{
super("Fakturowanie");
setContentPane(rootPanel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
tabbedPane1.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
newClientButton.addActionListener(this);
removeClientButton.addActionListener(this);
printButton.addActionListener(this);
pack();
setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e)
{
Object button = e.getSource();
TmpPanel tmp = new TmpPanel();
if(button == newClientButton)
{
String name = JOptionPane.showInputDialog(this, "Nazwa sprzedawcy:\n", "Nowy sprzedawca",
JOptionPane.PLAIN_MESSAGE);
if((name != null) && (name.length() > 0))
{
tabbedPane1.addTab(name, tmp.getContentPane());
pack();
}
}
if(button == removeClientButton)
{
tabbedPane1.remove(tabbedPane1.getSelectedComponent());
}
if(button == printButton)
{
System.out.println(tabbedPane1.isValid());
printComponent(tmp.getPrintablePanel());
}
}
public void printComponent(Component comp)
{
PrinterJob printerJob = PrinterJob.getPrinterJob();
PageFormat pf = printerJob.pageDialog(printerJob.defaultPage());
printerJob.setPrintable(new ComponentPrintable(comp), pf);
if(printerJob.printDialog())
{
try
{
printerJob.print();
}
catch (PrinterException e1)
{
JOptionPane.showMessageDialog(this, "Błąd drukowania", "Błąd", JOptionPane.OK_OPTION);
}
}
}
}
Now my problem is as follows: I want to print printPanel from TmpPanel so that it fits the page. Previously in printButton listener I had
printComponent(tabbedPane1.getSelectedComponent());
and it worked perfectly. But when I type
printComponent(tmp.getPrintablePanel());
I only get a background color of printPanel (I made it black to make it visible on a blank page). I tried all the combinations with extend JPanel, extend JFrame, add, setContentPane, getContentPane etc but nothing works. I only managed to find out this little thing: When I type
System.out.println(tabbedPane1.getSelectedComponent().isValid());
it returns true. When I try to validate or repaint each component in TmpPanel the isValid method return false for each of them.
I guess that's why I can only see a black rectangle of printPanels background after pressing Print button.
Why is that even though both forms were created in designer and how get this to work?
So, part of the problem, as I see it, is some the components don't want to render until they are attached to a native peer (or realised window).
There are two choices, you could simply print the live component which is already on the screen. This is a problem, because the ComponentPrintable will change the size of the component, which will affect the live component, making it somewhat unpleasant to the user.
The second option is to create a new instance of the component and place it on another JFrame. The tricky part is getting the frame to realise it self and create a native peer.
Luckily, there are a couple of methods which we know can do this, pack been one of them.
The following example is taken from the Using Text Components example, as it's a realitvly complex component.
When you click print, it makes a new instance of this component, add's it to a JFrame, packs the frame and then prints the component.
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import static java.awt.print.Printable.PAGE_EXISTS;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.IOException;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.text.BadLocationException;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JButton print = new JButton("Print");
print.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
TextSamplerDemo demo = new TextSamplerDemo();
JFrame test = new JFrame();
test.add(demo);
test.pack();
ComponentPrintable printable = new ComponentPrintable(demo);
PrinterJob printerJob = PrinterJob.getPrinterJob();
PageFormat pf = printerJob.pageDialog(printerJob.defaultPage());
printerJob.setPrintable(printable, pf);
if (printerJob.printDialog()) {
try {
printerJob.print();
} catch (PrinterException e1) {
JOptionPane.showMessageDialog(null, "Printing failed", "Print", JOptionPane.OK_OPTION);
}
}
}
});
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TextSamplerDemo demo = new TextSamplerDemo();
frame.add(demo);
frame.add(print, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ComponentPrintable extends JPanel implements Printable {
private Component comp;
public ComponentPrintable(Component comp) {
this.comp = comp;
}
#Override
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
if (pageIndex > 0) {
return Printable.NO_SUCH_PAGE;
}
Dimension componentSize = comp.getPreferredSize();
comp.setSize(componentSize);
Dimension printSize = new Dimension();
printSize.setSize(pageFormat.getImageableWidth(), pageFormat.getImageableHeight());
double scaleFactor = getScaleFactorToFit(componentSize, printSize);
if (scaleFactor > 1d) {
scaleFactor = 1d;
}
double scaleWidth = componentSize.width * scaleFactor;
double scaleHeight = componentSize.height * scaleFactor;
Graphics2D g2 = (Graphics2D) graphics;
double x = ((pageFormat.getImageableWidth() - scaleWidth) / 2d) + pageFormat.getImageableX();
double y = ((pageFormat.getImageableHeight() - scaleHeight) / 2d) + pageFormat.getImageableY();
AffineTransform at = new AffineTransform();
at.translate(x, y);
at.scale(scaleFactor, scaleFactor);
g2.transform(at);
comp.printAll(g2);
g2.dispose();
comp.revalidate();
return PAGE_EXISTS;
}
private double getScaleFactorToFit(Dimension original, Dimension toFit) {
double dScale = 1d;
if (original != null && toFit != null) {
double dScaleWidth = getScaleFactor(original.width, toFit.width);
double dScaleHeight = getScaleFactor(original.height, toFit.height);
dScale = Math.min(dScaleHeight, dScaleWidth);
}
return dScale;
}
private double getScaleFactor(int iMasterSize, int iTargetSize) {
double dScale = 1;
if (iMasterSize > iTargetSize) {
dScale = (double) iTargetSize / (double) iMasterSize;
} else {
dScale = (double) iTargetSize / (double) iMasterSize;
}
return dScale;
}
}
public class TextSamplerDemo extends JPanel
implements ActionListener {
private String newline = "\n";
protected static final String textFieldString = "JTextField";
protected static final String passwordFieldString = "JPasswordField";
protected static final String ftfString = "JFormattedTextField";
protected static final String buttonString = "JButton";
protected JLabel actionLabel;
public TextSamplerDemo() {
setLayout(new BorderLayout());
//Create a regular text field.
JTextField textField = new JTextField(10);
textField.setActionCommand(textFieldString);
textField.addActionListener(this);
//Create a password field.
JPasswordField passwordField = new JPasswordField(10);
passwordField.setActionCommand(passwordFieldString);
passwordField.addActionListener(this);
//Create a formatted text field.
JFormattedTextField ftf = new JFormattedTextField(
java.util.Calendar.getInstance().getTime());
ftf.setActionCommand(textFieldString);
ftf.addActionListener(this);
//Create some labels for the fields.
JLabel textFieldLabel = new JLabel(textFieldString + ": ");
textFieldLabel.setLabelFor(textField);
JLabel passwordFieldLabel = new JLabel(passwordFieldString + ": ");
passwordFieldLabel.setLabelFor(passwordField);
JLabel ftfLabel = new JLabel(ftfString + ": ");
ftfLabel.setLabelFor(ftf);
//Create a label to put messages during an action event.
actionLabel = new JLabel("Type text in a field and press Enter.");
actionLabel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
//Lay out the text controls and the labels.
JPanel textControlsPane = new JPanel();
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
textControlsPane.setLayout(gridbag);
JLabel[] labels = {textFieldLabel, passwordFieldLabel, ftfLabel};
JTextField[] textFields = {textField, passwordField, ftf};
addLabelTextRows(labels, textFields, gridbag, textControlsPane);
c.gridwidth = GridBagConstraints.REMAINDER; //last
c.anchor = GridBagConstraints.WEST;
c.weightx = 1.0;
textControlsPane.add(actionLabel, c);
textControlsPane.setBorder(
BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Text Fields"),
BorderFactory.createEmptyBorder(5, 5, 5, 5)));
//Create a text area.
JTextArea textArea = new JTextArea(
"This is an editable JTextArea. "
+ "A text area is a \"plain\" text component, "
+ "which means that although it can display text "
+ "in any font, all of the text is in the same font."
);
textArea.setFont(new Font("Serif", Font.ITALIC, 16));
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
JScrollPane areaScrollPane = new JScrollPane(textArea);
areaScrollPane.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
areaScrollPane.setPreferredSize(new Dimension(250, 250));
areaScrollPane.setBorder(
BorderFactory.createCompoundBorder(
BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Plain Text"),
BorderFactory.createEmptyBorder(5, 5, 5, 5)),
areaScrollPane.getBorder()));
//Create an editor pane.
JEditorPane editorPane = createEditorPane();
JScrollPane editorScrollPane = new JScrollPane(editorPane);
editorScrollPane.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
editorScrollPane.setPreferredSize(new Dimension(250, 145));
editorScrollPane.setMinimumSize(new Dimension(10, 10));
//Create a text pane.
JTextPane textPane = createTextPane();
JScrollPane paneScrollPane = new JScrollPane(textPane);
paneScrollPane.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
paneScrollPane.setPreferredSize(new Dimension(250, 155));
paneScrollPane.setMinimumSize(new Dimension(10, 10));
//Put the editor pane and the text pane in a split pane.
JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
editorScrollPane,
paneScrollPane);
splitPane.setOneTouchExpandable(true);
splitPane.setResizeWeight(0.5);
JPanel rightPane = new JPanel(new GridLayout(1, 0));
rightPane.add(splitPane);
rightPane.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Styled Text"),
BorderFactory.createEmptyBorder(5, 5, 5, 5)));
//Put everything together.
JPanel leftPane = new JPanel(new BorderLayout());
leftPane.add(textControlsPane,
BorderLayout.PAGE_START);
leftPane.add(areaScrollPane,
BorderLayout.CENTER);
add(leftPane, BorderLayout.LINE_START);
add(rightPane, BorderLayout.LINE_END);
}
private void addLabelTextRows(JLabel[] labels,
JTextField[] textFields,
GridBagLayout gridbag,
Container container) {
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.EAST;
int numLabels = labels.length;
for (int i = 0; i < numLabels; i++) {
c.gridwidth = GridBagConstraints.RELATIVE; //next-to-last
c.fill = GridBagConstraints.NONE; //reset to default
c.weightx = 0.0; //reset to default
container.add(labels[i], c);
c.gridwidth = GridBagConstraints.REMAINDER; //end row
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1.0;
container.add(textFields[i], c);
}
}
public void actionPerformed(ActionEvent e) {
String prefix = "You typed \"";
if (textFieldString.equals(e.getActionCommand())) {
JTextField source = (JTextField) e.getSource();
actionLabel.setText(prefix + source.getText() + "\"");
} else if (passwordFieldString.equals(e.getActionCommand())) {
JPasswordField source = (JPasswordField) e.getSource();
actionLabel.setText(prefix + new String(source.getPassword())
+ "\"");
} else if (buttonString.equals(e.getActionCommand())) {
Toolkit.getDefaultToolkit().beep();
}
}
private JEditorPane createEditorPane() {
JEditorPane editorPane = new JEditorPane();
editorPane.setEditable(false);
java.net.URL helpURL = TextSamplerDemo.class.getResource(
"TextSamplerDemoHelp.html");
if (helpURL != null) {
try {
editorPane.setPage(helpURL);
} catch (IOException e) {
System.err.println("Attempted to read a bad URL: " + helpURL);
}
} else {
System.err.println("Couldn't find file: TextSampleDemoHelp.html");
}
return editorPane;
}
private JTextPane createTextPane() {
String[] initString
= {"This is an editable JTextPane, ", //regular
"another ", //italic
"styled ", //bold
"text ", //small
"component, ", //large
"which supports embedded components..." + newline,//regular
" " + newline, //button
"...and embedded icons..." + newline, //regular
" ", //icon
newline + "JTextPane is a subclass of JEditorPane that "
+ "uses a StyledEditorKit and StyledDocument, and provides "
+ "cover methods for interacting with those objects."
};
String[] initStyles
= {"regular", "italic", "bold", "small", "large",
"regular", "button", "regular", "icon",
"regular"
};
JTextPane textPane = new JTextPane();
StyledDocument doc = textPane.getStyledDocument();
addStylesToDocument(doc);
try {
for (int i = 0; i < initString.length; i++) {
doc.insertString(doc.getLength(), initString[i],
doc.getStyle(initStyles[i]));
}
} catch (BadLocationException ble) {
System.err.println("Couldn't insert initial text into text pane.");
}
return textPane;
}
protected void addStylesToDocument(StyledDocument doc) {
//Initialize some styles.
Style def = StyleContext.getDefaultStyleContext().
getStyle(StyleContext.DEFAULT_STYLE);
Style regular = doc.addStyle("regular", def);
StyleConstants.setFontFamily(def, "SansSerif");
Style s = doc.addStyle("italic", regular);
StyleConstants.setItalic(s, true);
s = doc.addStyle("bold", regular);
StyleConstants.setBold(s, true);
s = doc.addStyle("small", regular);
StyleConstants.setFontSize(s, 10);
s = doc.addStyle("large", regular);
StyleConstants.setFontSize(s, 16);
s = doc.addStyle("icon", regular);
StyleConstants.setAlignment(s, StyleConstants.ALIGN_CENTER);
ImageIcon pigIcon = createImageIcon("images/Pig.gif",
"a cute pig");
if (pigIcon != null) {
StyleConstants.setIcon(s, pigIcon);
}
s = doc.addStyle("button", regular);
StyleConstants.setAlignment(s, StyleConstants.ALIGN_CENTER);
ImageIcon soundIcon = createImageIcon("images/sound.gif",
"sound icon");
JButton button = new JButton();
if (soundIcon != null) {
button.setIcon(soundIcon);
} else {
button.setText("BEEP");
}
button.setCursor(Cursor.getDefaultCursor());
button.setMargin(new Insets(0, 0, 0, 0));
button.setActionCommand(buttonString);
button.addActionListener(this);
StyleConstants.setComponent(s, button);
}
protected ImageIcon createImageIcon(String path,
String description) {
java.net.URL imgURL = TextSamplerDemo.class.getResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL, description);
} else {
System.err.println("Couldn't find file: " + path);
return null;
}
}
}
}
For this to work realistically, you would need to make a copy of all the data which the panel contained originally, otherwise it's kind of pointless
I managed to solve it somehow by modyfying TmpPanel constructor with
public TmpPanel()
{
setContentPane(panel1);
pack();
dispose();
}
now isValid returned true for all components. Each time printButton is pressed a new invisible JFrame with the printPanel is created but I dispose it immidiately so no desktop space neither extra memory is used. I can now print easily with
printComponent(tmp.getPrintablePanel());
Related
I am working with a list of elements that I want to rank. Ideally the program would randomly choose 2 elements to compare and present them, sort the list with the new ranking, then select 2 more so the user could pick the winner over and over again until the user wanted to stop. The parts I am having trouble with are:
getting the button to interact with the object to change its rank and
getting the JFrame to close and reopen with new elements to compare
I created a class called action that is supposed to handle the clicks:
public class action extends JFrame implements ActionListener{
private JButton b1;
private JButton b2;
private JButton b3;
private JPanel jp;
public action(Bond one, Bond two){
//JFrame mf = new JFrame("My Frame");
//JPanel jp = new JPanel();
jp = new JPanel();
setSize(500,500);
setVisible(true);
setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
b1 = new JButton(one.name+"\nRating: "+one.rating);
b1.addActionListener(this);
b2 = new JButton(two.name);
b2.addActionListener(this);
b3 = new JButton("Tie");
b3.addActionListener(this);
jp.add(b1);
jp.add(b2);
jp.add(b3);
add(jp);
}
public void actionPerformed(ActionEvent e){
int clickCount = 0;
if (clickCount > 3) {
System.exit(0);
}
JOptionPane jo = new JOptionPane();
if(e.getSource() == b1){
// jo.showMessageDialog(null, "button 1");
clickCount++;
//System.exit(0);
}
if(e.getSource() == b2){
jo.showMessageDialog(null, "button 2");
clickCount++;
//System.exit(0);
}
if(e.getSource() == b3){
jo.showMessageDialog(null, "button 3");
clickCount++;
//System.exit(0);
}
}
}
And here is how I am calling the action class from my main:
while(compCount < 3){
//these generate random numbers that correspond with the index of the elements to be compared
//comp is the name of the list of objects
int r1 = r.nextInt(comp.size());
int r2 = r.nextInt(comp.size());
int t;
if(r1 == r2){
continue;
}
else{
action a = new action(comp.get(r1), comp.get(r2));
compCount++;
}
}
Currently this just creates 3 popup windows that do nothing when I click the buttons.
Any help or insight would be appreciated!
The OP wants to make a complex Swing GUI. He didn't provide a minimal, runnable, example, so I created my own.
The best way to make a complex Swing GUI is to construct it one small piece at a time. By testing each small piece in isolation, you too can construct a complex GUI.
Here's the GUI I created.
The object of this game is to choose your favorite characters from the lower case characters of the English alphabet. You can left-click on the Pass button if neither character is among your favorites.
I'd already written the JPanel to display a character for a previous Stack Overflow answer.
The first thing I did was create the main class. I named this class FavoriteCharacter.
I called the SwingUtilities invokeLater method to ensure that the Swing components were created and executed on the Event Dispatch Thread.
Next, I wrote the JFrame code. The JFrame code is nearly identical for every Swing GUI I create. The JFrame code is located in the run method of the FavoriteCharacter class.
Next, I wrote the model class, the LetterMap class. Whenever I create a complex Swing GUI, I use the model / view / controller pattern. This model is pretty simple. I have a map that contains the lower case characters of the English alphabet, along with vote counts.
Once I had the model working, I went back to creating the view. Each small part of the GUI is contained in a method of the FavoriteCharacter class. That way, I could test each small piece of the view individually. No throwing spaghetti code against the wall and seeing what sticks for me.
The actual drawing of the characters happens in a LetterPanel class. All Swing custom painting must be done in the paintComponent method of a JPanel.
After I finished the GUI, I worked on the two controller classes, PassListener and VoteListener. PassListener calls a method in the FavoriteCharacters class to select another pair of characters. VoteListener updates the LetterMap model class, displays the vote total for the selected character in a JOptionPane, and selects another pair of letters.
Here's the runnable, example code.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class FavoriteCharacter implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new FavoriteCharacter());
}
private char[] letterPair;
private JFrame frame;
private LetterMap letterMap;
private LetterPanel letterPanel1;
private LetterPanel letterPanel2;
public FavoriteCharacter() {
this.letterMap = new LetterMap();
this.letterPair = letterMap.pickTwo();
}
#Override
public void run() {
frame = new JFrame("Favorite Character");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createTitlePanel(),
BorderLayout.BEFORE_FIRST_LINE);
frame.add(createMainPanel(letterPair),
BorderLayout.CENTER);
frame.add(createSkipPanel(),
BorderLayout.AFTER_LAST_LINE);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createTitlePanel() {
JPanel panel = new JPanel();
JLabel label = new JLabel("Vote for your favorite character");
label.setHorizontalAlignment(JLabel.CENTER);
panel.add(label);
return panel;
}
private JPanel createMainPanel(char[] letterPair) {
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
panel.add(Box.createHorizontalStrut(10));
letterPanel1 = new LetterPanel(Color.WHITE, letterPair[0]);
panel.add(createLetterPanel(letterPanel1, "0"));
panel.add(Box.createHorizontalStrut(10));
letterPanel2 = new LetterPanel(Color.WHITE, letterPair[1]);
panel.add(createLetterPanel(letterPanel2, "1"));
panel.add(Box.createHorizontalStrut(10));
return panel;
}
private void updateLetterPanels() {
letterPanel1.setLetter(letterPair[0]);
letterPanel2.setLetter(letterPair[1]);
letterPanel1.repaint();
letterPanel2.repaint();
}
private void updateLetterPair() {
letterPair = letterMap.pickTwo();
System.out.println(Arrays.toString(letterPair));
updateLetterPanels();
}
private JPanel createLetterPanel(LetterPanel letterPanel,
String actionCommand) {
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.CENTER;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(0, 10, 10, 10);
gbc.weightx = 0d;
panel.add(letterPanel, gbc);
gbc.gridy++;
gbc.weightx = 1d;
JButton button = new JButton("Vote");
button.setActionCommand(actionCommand);
button.setHorizontalAlignment(JButton.CENTER);
button.addActionListener(new VoteListener());
panel.add(button, gbc);
return panel;
}
private JPanel createSkipPanel() {
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.CENTER;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(0, 18, 10, 18);
gbc.weightx = 1d;
JButton button = new JButton("Pass");
button.setHorizontalAlignment(JButton.CENTER);
button.addActionListener(new PassListener());
panel.add(button, gbc);
return panel;
}
public class LetterPanel extends JPanel {
private static final long serialVersionUID = 1L;
private char letter;
private Color backgroundColor;
private Font font;
public LetterPanel(Color backgroundColor, char letter) {
this.backgroundColor = backgroundColor;
this.letter = letter;
this.font = getFont().deriveFont(96f)
.deriveFont(Font.BOLD);
this.setBorder(BorderFactory.createLineBorder(
Color.GREEN, 6));
this.setPreferredSize(new Dimension(120, 200));
}
public void setLetter(char letter) {
this.letter = letter;
}
public char getLetter() {
return letter;
}
public LetterPanel getLetterPanel() {
return this;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(backgroundColor);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setColor(Color.BLACK);
drawCenteredString(g2d, Character.toString(letter),
font);
}
/**
* Draw a String centered in the middle of the panel.
*
* #param g2d The Graphics2D instance.
* #param text The String to draw.
* #param font The Font to draw with.
*/
public void drawCenteredString(Graphics2D g2d,
String text, Font font) {
FontMetrics metrics = g2d.getFontMetrics(font);
int x = (getWidth() - metrics.stringWidth(text)) / 2;
int y = ((getHeight() - metrics.getHeight()) / 2) +
metrics.getAscent();
g2d.setFont(font);
g2d.drawString(text, x, y);
}
}
public class PassListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent event) {
updateLetterPair();
}
}
public class VoteListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent event) {
int index = Integer.valueOf(event.getActionCommand());
char c = letterPair[index];
letterMap.addVote(c);
int votes = letterMap.getVotes(c);
showMessageDialog(c, votes);
}
private void showMessageDialog(char c, int votes) {
String text = "The character '" + c + "' has ";
text += Integer.toString(votes);
if (votes == 1) {
text += " vote.";
} else {
text += " votes.";
}
JOptionPane.showMessageDialog(frame, text);
updateLetterPair();
}
}
public class LetterMap {
private Map<Character, Integer> letterMap;
private Random random;
public LetterMap() {
this.letterMap = createLetterMap();
this.random = new Random();
}
private Map<Character, Integer> createLetterMap() {
Map<Character, Integer> letterMap = new TreeMap<>();
for (int i = 0; i < 26; i++) {
Character c = (char) (i + 'a');
letterMap.put(c, 0);
}
return letterMap;
}
public char[] pickTwo() {
int index1 = random.nextInt(letterMap.size());
int index2 = random.nextInt(letterMap.size());
while (index2 == index1) {
index2 = random.nextInt(letterMap.size());
}
char[] output = new char[2];
Set<Character> letterSet = letterMap.keySet();
Iterator<Character> iter = letterSet.iterator();
int count = 0;
int index3 = 0;
while (iter.hasNext() && index3 < 2) {
Character key = iter.next();
if (count == index1 || count == index2) {
if (index3 < 2) {
output[index3++] = key;
}
}
count++;
}
return output;
}
public void addVote(char c) {
Integer vote = getVotes(c);
letterMap.put(c, ++vote);
}
public int getVotes(char c) {
return letterMap.get(c);
}
}
}
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.
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 have to Add some points in my following GUI. Following is the Code i have done so far
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import javax.swing.*;
public class PoiS extends JFrame implements ActionListener{
JPanel p;
JButton bplus, bminus;
double factor = 0.5;
JPanel titlePanel;
JLabel redLabel;
PoiS(){
p = new DrawingPanel();
/*
buttonMinus = new JButton("Zoom In");
buttonPlus = new JButton(" Zoom Out ");
buttonMinus.addActionListener(this);
buttonPlus.addActionListener(this);
Box box = Box.createHorizontalBox();
box.add(Box.createHorizontalGlue());
box.add(buttonMinus);
box.add(Box.createHorizontalStrut(20));
box.add(buttonPlus);
box.add(Box.createHorizontalGlue());
add(box, BorderLayout.SOUTH);
*/
//Here i was creating a new Panel To enter to my Original panel P
titlePanel = new JPanel();
titlePanel.setLayout(null);
titlePanel.setLocation(10, 0);
titlePanel.setSize(250, 30);
p.add(titlePanel);
/*
redLabel = new JLabel("Red Team");
redLabel.setLocation(0, 0);
redLabel.setSize(120, 30);
redLabel.setHorizontalAlignment(0);
redLabel.setForeground(Color.red);
titlePanel.add(redLabel);*/
bplus = new JButton("+");
bminus = new JButton("-");
bplus.addActionListener(this);
bminus.addActionListener(this);
Box box = Box.createHorizontalBox();
box.add(Box.createHorizontalGlue());
box.add(bminus);
box.add(Box.createHorizontalStrut(20));
box.add(bplus);
box.add(Box.createHorizontalGlue());
add(box, BorderLayout.SOUTH);
//add(new JLabel("\n"),BorderLayout.NORTH);
//add(new JLabel(" subash "),BorderLayout.EAST);
//add(new JLabel(" kafley "),BorderLayout.WEST);
JLabel lbl = new JLabel();
lbl.setText("Hotel1");
//lbl.setText("hotel1");
lbl.setLocation(20,20);
lbl.setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(600,400);
setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == bplus) {
factor += 0.1;
}
else {
factor -= 0.1;
}
bminus.setEnabled(factor > 0.1);
bplus.setEnabled(factor < 4.0);
p.repaint();
JLabel redLabel = new JLabel("Red Team");
redLabel.setLocation(0, 0);
redLabel.setSize(120, 30);
redLabel.setHorizontalAlignment(0);
redLabel.setForeground(Color.red);
//redLabel.setVisible(true);
redLabel.add(p);
//redLabel.setVisible(true);
}
public static void main(String []arg) {
/* File file = new i was trying to get my x axis and y axis from the txt file File("/Users/kafley/Documents/Studymaterial/ITC313/Assignment1/src/Points.txt");
FileReader fr = new FileReader(file);
BufferedReader in = new BufferedReader(fr);
String line;
while ((line = in.readLine()) != null){
String[] record = line.split(",\\s*");
for(int i=0;i<record.length; i++){
System.out.print(record[i]);*/
/*String line;
try {
BufferedReader reader = new BufferedReader(new FileReader("/Users/kafley/Documents/Studymaterial/ITC313/Assignment1/src/Points.txt"));
while((line = reader.readLine()) != null){
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}*/
PoiS print = new PoiS();
JLabel lbl = new JLabel();
lbl.setText("Hotel1");
lbl.setLocation(20, 20);
lbl.setVisible(true);
}
}
and another class
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
/**
*
* #author kafley
*/
class DrawingPanel extends JPanel {
double squareSize[] = {100.0, 50.0};
double factor = 0.5;
DrawingPanel() {
super(null);
setBorder(BorderFactory.createLineBorder(Color.RED));
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Dimension dim = this.getSize();
int width = dim.width - 10;
int height = dim.height - 10;
for(int i = 0; i < squareSize.length; ++i) {
int squareWidth = (int) (squareSize[i] * factor);
int x = (width - squareWidth) / 2;
int y = (height - squareWidth) / 2;
g.drawRect(x, y, squareWidth, squareWidth);
}
}
}
Just Ignore Those Comment Parts as copy paste from my Netbeans
I didn't want to delete because I thougt I might need it in future. I just want you to help me to plot another JPanel in this Frame. Any help will be Appreciated
I'm not sure... but is this ok?:
redLabel.add(p);// <- redLabel is JLabel,and p is JPanel...?
If I've understood the problem... you should also add redLabel to some panel.
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: