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.
Related
OK, So I have a program that displays a a String on a JPanel and it draws the lines of where the Ascents are, it draws a line at the Descent and halfway between, and a quarter way between. I have a combo box to change the font and the size of the String, and i have a JTextField to change the Text itself. I used actionListeners to update the String. Whenever i update the text of the String via the JTextField, the program glitches out, and shows a copy of the image of the JTextField on the top right corner of the JFrame.
Code:
package com.Patel.RichClients;
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.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
//a class to demonstrate
public class StringAscent extends JFrame {
private static Font font;
private int fontSize = 50;
private StringPanel panel;
private JComboBox fontOptions;
private JComboBox fontSizeOptions;
private JTextField text;
// constructor
public StringAscent() {
// set the initial font to Times new Roman
font = new Font("Agency FB", Font.PLAIN, fontSize);
setVisible(true);
setSize(520, 170);
setTitle("String Ascents");
setLayout(new BorderLayout());
//set up the components
GraphicsEnvironment ge= GraphicsEnvironment.getLocalGraphicsEnvironment();
String[] fontNames = ge.getAvailableFontFamilyNames();
fontOptions = new JComboBox(fontNames);
text = new JTextField(22);
text.setText("Swing");
String[] sizeOptions = new String[50];
for (int i = 0; i < sizeOptions.length; i ++){
sizeOptions[i] = Integer.toString(i + 1);
}
fontSizeOptions = new JComboBox(sizeOptions);
panel = new StringPanel();
//set up actionListeners
fontOptions.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
JComboBox ref = (JComboBox) e.getSource();
font = new Font(fontNames[ref.getSelectedIndex()], Font.PLAIN, fontSize);
panel.repaint();
}
});
fontSizeOptions.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
JComboBox ref = (JComboBox) e.getSource();
fontSize = Integer.parseInt(sizeOptions[ref.getSelectedIndex()]);
font = new Font(font.getName(), Font.PLAIN, fontSize);
panel.repaint();
}
});
text.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
panel.repaint();
}
});
//add components
add(panel, BorderLayout.NORTH);
add(fontOptions, BorderLayout.WEST);
add(text, BorderLayout.CENTER);
add(fontSizeOptions, BorderLayout.EAST);
}
public static void main(String[] args) {
Runnable showGui = new Runnable() {
public void run() {
StringAscent gui = new StringAscent();
}
};
SwingUtilities.invokeLater(showGui);
}
// inner JPanel class
private class StringPanel extends JPanel {
// constructor
public StringPanel() {
}
public Dimension getPreferredSize() {
return new Dimension(400, 100);
}
public void paintComponent(Graphics g) {
g.setColor(Color.black);
// set up the string
g.setFont(font);
// FontMetric is an object that holds information relevant to the
// rendering of the font
FontMetrics metric = g.getFontMetrics();
int ascent = metric.getAscent();
String string = text.getText();
g.drawString(string, 100, 50);
int x = 50;
// draw Ascent line
g.drawLine(x, 50 - ascent, x + 180, 50 - ascent);
// draw Ascent/2 line
g.drawLine(x, 50 - (ascent / 2), x + 180, 50 - (ascent / 2));
// draw Ascent/4 line
g.drawLine(x, 50 - (ascent / 4), x + 180, 50 - (ascent / 4));
// draw baseline line
g.drawLine(x, 50, x + 180, 50);
// draw Descent line
g.drawLine(x, 50 + metric.getDescent(), x + 180, 50 + metric.getDescent());
}
}
}
Add super.paintComponent(g) to the start of your paintComponent method
public void paintComponent(Graphics g) {
super.paintComponent(g)
g.setColor(Color.black);
//...
Basically, one of the jobs of paintComponent is to prepare the Graphics context for painting the current component. In Swing, the Graphics is a shared resource which is used by all the components within a window when been painted, so it's important to make sure that context is prepared properly before you paint on it
Take a look at Performing Custom Painting and Painting in AWT and Swing for more details about how painting works
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());
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);
}
}
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.
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: