I've read all the topics regarding this issue,and i can't figure out what's the problem.
The following code is inside a method that gets called on button click, the buttons were dynamically generated, and yes the console output is showing, so the method is getting called.
System.out.println("loaditems method");
final JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(436, 480));
panel.setLayout(new FlowLayout(FlowLayout.LEFT,5,5));
panel.setBackground(Color.gray);
panel.setBorder(BorderFactory.createEtchedBorder(LOWERED, Color.lightGray, Color.gray));
panel.setOpaque(false);
panel.setLocation(jMainPanel.getLocation());
panel.setVisible(true);
jLayeredPane1.add(panel);
jLayeredPane1.revalidate();
JLayeredPane uses null-layout by default. So you should implement your own LayoutManager to set the bounds of each component located in the JLayeredPane.
See this example:
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.LayoutManager;
import java.awt.Rectangle;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestJLayeredPane {
public static class AbsoluteLayoutManager implements LayoutManager {
private Map<Component, Rectangle> bounds = new LinkedHashMap<Component, Rectangle>();
#Override
public void addLayoutComponent(String name, Component comp) {
bounds.put(comp, new Rectangle(comp.getPreferredSize()));
}
#Override
public void removeLayoutComponent(Component comp) {
bounds.remove(comp);
}
#Override
public Dimension preferredLayoutSize(Container parent) {
Rectangle rect = new Rectangle();
for (Rectangle r : bounds.values()) {
rect = rect.union(r);
}
return rect.getSize();
}
#Override
public Dimension minimumLayoutSize(Container parent) {
return preferredLayoutSize(parent);
}
#Override
public void layoutContainer(Container parent) {
for (Entry<Component, Rectangle> e : bounds.entrySet()) {
e.getKey().setBounds(e.getValue());
}
}
public void setBounds(Component c, Rectangle bounds) {
this.bounds.put(c, bounds);
}
}
protected void initUI() {
JFrame frame = new JFrame("test");
AbsoluteLayoutManager layout = new AbsoluteLayoutManager();
JLayeredPane layeredPane = new JLayeredPane();
layeredPane.setLayout(layout);
final JPanel panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));
panel.setBackground(Color.gray);
panel.setVisible(true);
layeredPane.add(panel);
layout.setBounds(panel, new Rectangle(17, 59, 436, 480));
frame.add(layeredPane);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
UnsupportedLookAndFeelException {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TestJLayeredPane().initUI();
}
});
}
}
Related
Below is a small example where two radio buttons are offset too far to the left column.
However, if I remove the "A" button above by commenting out this code:
Then the 2 radio buttons are displayed as expected and not offset:
How do I get the radio buttons aligned correctly like the second case, but with the button present? Here is the code:
Main.java:
package layoutdemo;
import java.awt.Color;
import java.awt.Frame;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
public class Main extends JFrame {
public Main() {
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setExtendedState(Frame.MAXIMIZED_BOTH);
getContentPane().setLayout(new BoxLayout(this.getContentPane(), BoxLayout.X_AXIS));
getContentPane().setBackground(Color.black);
add(new LeftPanel());
pack();
setVisible(true);
}
public static void main(String args[]) {
new Main();
}
}
LeftPanel.java:
package layoutdemo;
import java.awt.Component;
import java.awt.Dimension;
import javax.swing.BoxLayout;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
public class LeftPanel extends JPanel {
public LeftPanel() {
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
//add(new ButtonPanel());
add(new JRadioButton("RadioBut2"));
add(new JRadioButton("RadioBut1"));
}
#Override
public Dimension getPreferredSize() {
Component p = getParent();
while(p.getParent() != null) {
p = p.getParent();
}
Dimension dimension = p.getSize();
return new Dimension(100, (int) (dimension.getHeight()));
}
#Override
public Dimension getMaximumSize() {
return getPreferredSize();
}
}
ButtonPanel.java:
package layoutdemo;
import java.awt.Component;
import java.awt.Dimension;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
public class ButtonPanel extends JPanel {
public ButtonPanel() {
add(new JToggleButton("A"));
}
#Override
public Dimension getPreferredSize() {
Component p = getParent();
while(p.getParent() != null) {
p = p.getParent();
}
Dimension dimension = p.getSize();
return new Dimension(dimension.width, 50);
}
#Override
public Dimension getMaximumSize() {
return getPreferredSize();
}
}
It could be to do with the "alignmentX" property for those items. Trying setting all those items to the same alignmentX value.
I want to add 100 buttons into an GridLayout and my code works but sometimes it only adds one button and if I click where the other buttons belong the button where I clicked appears.
it happens totally randomly and I don't get it.
Here is my code:
public class GamePanel extends JPanel {
GameUI controler;
GridLayout gameLayout = new GridLayout(10,10);
JButton gameButtons[] = new JButton[100];
ImageIcon ice;
JButton startButton;
JButton exitButton;
ImageIcon startIcon;
ImageIcon exitIcon;
URL urlIcon;
private int i;
public GamePanel(GameUI controler) {
this.setLayout(gameLayout);
this.controler = controler;
urlIcon = this.getClass().getResource("/icons/Overlay.png");
ice = new ImageIcon(urlIcon);
makeButtons();
}
#Override
public void paint(Graphics g) {
super.paint(g);
}
public void makeButtons() {
for(i = 0; i< 100; i++) {
gameButtons[i] = new JButton(ice);
this.add(gameButtons[i]);
revalidate();
}
repaint();
}
}
update:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.net.URL;
public class GameUI extends JFrame {
ImageIcon i;
Image jFrameBackground;
JButton startButton;
JButton exitButton;
ImageIcon startIcon;
ImageIcon exitIcon;
public GameUI() {
setResizable(false);
this.setSize(1200, 800);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(null);
BackGroundPanel backGroundPanel = new BackGroundPanel();
GamePanel panel = new GamePanel(this);
ButtonPanel buttonPanel = new ButtonPanel();
panel.setSize(500,500);
panel.setLocation(100, 150);
backGroundPanel.setSize(this.getWidth(),this.getHeight());
backGroundPanel.setLocation(0,0);
buttonPanel.setSize(390,50);
buttonPanel.setLocation(100,100);
this.add(backGroundPanel);
this.add(panel);
this.add(buttonPanel);
backGroundPanel.setBackground(Color.BLACK);
}
public static void main(String[] args) throws InvocationTargetException, InterruptedException {
javax.swing.SwingUtilities.invokeAndWait(
new Runnable(){
#Override
public void run() {
GameUI ui = new GameUI();
ui.setVisible(true);
}
}
);
}
}
As I mentioned in comments, you're using a null layout, and this is the source of your problems.
You're using the null layout to try to layer JPanels, one on top of the other, and that is not how it should be used or what it is for, nor how you should create backgrounds. This is having the effect of the background covering your buttons until your mouse hovers over them.
Instead if you wish to create a background image, I would recommend that you:
create a JPanel, say called BackgroundPanel,
override its paintComponent method,
call its super.paintComponent(g); on your method's first line
then draw the image it should display
then give it a decent layout manager
and add your GUI components to it
Make sure that any JPanels added to it are made transparent via .setOpaque(false)
Other options include using a JLayeredPane, but you really don't need this just to have a background.
For example, the following code produces:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
public class GameUI2 {
private static final String IMG_PATH = "https://upload.wikimedia.org/wikipedia/commons/3/3f/"
+ "Butterfly_Nebula_in_narrow_band_Sulfur%2C_Hydrogen_and_Oxygen_Stephan_Hamel.jpg";
private static final String BTN_IMG_PATH = "https://upload.wikimedia.org/wikipedia/commons/5/54/Crystal_Project_Games_kids.png";
private static void createAndShowGui() {
BufferedImage bgImg = null;
BufferedImage btnImg = null;
try {
URL bgImgUrl = new URL(IMG_PATH);
URL btnImgUrl = new URL(BTN_IMG_PATH);
bgImg = ImageIO.read(bgImgUrl);
btnImg = ImageIO.read(btnImgUrl);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
BackgroundPanel2 mainPanel = new BackgroundPanel2(bgImg);
mainPanel.setLayout(new GridBagLayout());
GamePanel2 gamePanel = new GamePanel2(btnImg);
mainPanel.add(gamePanel);
JFrame frame = new JFrame("Game");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.setResizable(false);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
#SuppressWarnings("serial")
class BackgroundPanel2 extends JPanel {
private Image backgroundImg;
public BackgroundPanel2(Image backgroundImg) {
this.backgroundImg = backgroundImg;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (backgroundImg != null) {
g.drawImage(backgroundImg, 0, 0, this);
}
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet() || backgroundImg == null) {
return super.getPreferredSize();
} else {
int w = backgroundImg.getWidth(this);
int h = backgroundImg.getHeight(this);
return new Dimension(w, h);
}
}
}
#SuppressWarnings("serial")
class GamePanel2 extends JPanel {
public static final int MAX_BUTTONS = 100;
private static final int IMG_WIDTH = 40;
JButton[] gameButtons = new JButton[MAX_BUTTONS];
public GamePanel2(Image buttonImg) {
setOpaque(false);
if (buttonImg.getWidth(this) > IMG_WIDTH) {
buttonImg = buttonImg.getScaledInstance(IMG_WIDTH, IMG_WIDTH, Image.SCALE_SMOOTH);
}
Icon icon = new ImageIcon(buttonImg);
setLayout(new GridLayout(10, 10, 4, 4));
for (int i = 0; i < gameButtons.length; i++) {
int finalIndex = i;
JButton btn = new JButton(icon);
btn.addActionListener(e -> {
String text = String.format("Button: %02d", finalIndex);
System.out.println(text);
});
add(btn);
gameButtons[i] = btn;
}
}
}
I am attempting to use a FlowLayout to get my panels to align vertically. I want the bottom right to align toward the bottom of the top right panel, not the bottom of that row.
Here is what I have done:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class BigPanel extends JPanel {
#Override
public Component.BaselineResizeBehavior getBaselineResizeBehavior() {
return Component.BaselineResizeBehavior.CONSTANT_ASCENT;
}
#Override
public int getBaseline(int width, int height) {
return 0;
}
public BigPanel() {
FlowLayout layout = new FlowLayout();
layout.setAlignOnBaseline(true);
this.setLayout(layout);
this.add(new Panel1()); // size: 340x, 160y
this.add(new Panel2()); // size: 340x, 120y
this.add(new Panel3()); // size: 340x, 160y
this.add(new Panel4()); // size: 340x, 300y
}
}
How can I simply anchor panels and components to a set of coordinates? I have run into this problem many times this last week and use ridiculous workarounds for my jlabels, etc.
How it looks now:
There are probably a few ways you can achieve this, but the simplest would be to use compound layouts.
Use two panels to act as the columns and then place these onto the main container. Into these you would then place you other components.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
public class CompundLayout {
public static void main(String[] args) {
new CompundLayout();
}
public CompundLayout() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
JPanel left = new JPanel();
JPanel right = new JPanel();
setLayout(new GridLayout(0, 2, 2, 2));
left.add(createPane(Color.RED));
left.add(createPane(Color.GREEN));
right.add(createPane(Color.BLUE));
right.add(createPane(Color.MAGENTA));
add(left);
add(right);
}
protected JPanel createPane(Color color) {
SimplePane pane = new SimplePane();
pane.setBorder(new LineBorder(color));
return pane;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.dispose();
}
}
public class SimplePane extends JPanel {
private int width;
private int height;
public SimplePane() {
width = 100;
height = 50 + (int) Math.round(Math.random() * 100);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(width, height);
}
}
}
If I have a JPanel with multiple subcomponents, how would I make it so that JPanel remains a square despite how its parent is resized? I have tried variations on the following code, but it does not result in the subcomponents also being square.
public void paint(Graphics g){
if(this.isSquare()){
Dimension d = this.getSize();
if(d.height > d.width){
this.setSize(d.width, d.width);
} else {
this.setSize(d.height, d.height);
}
super.paint(g);
}
Here is an SSCCE.
The containing parent:
import javax.swing.JFrame;
public class TestFrame extends JFrame{
public TestFrame(){
this.add(new TestPanel());
}
public static void main(String[] args){
TestFrame tf = new TestFrame();
tf.setSize(500, 500);
tf.setVisible(true);
}
}
What should be a square JPanel:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
public class TestPanel extends JPanel{
private boolean isSquare;
public TestPanel(){
this.setSquare(true);
this.setLayout(new BorderLayout());
JLabel panel1 = new JLabel();
panel1.setBorder(new LineBorder(Color.RED, 4));
panel1.setBackground(Color.CYAN);
JLabel panel2 = new JLabel();
panel2.setBorder(new LineBorder(Color.BLUE, 4));
panel2.setBackground(Color.CYAN);
this.setBorder(new LineBorder(Color.GREEN, 4));
this.setBackground(Color.CYAN);
this.add(panel1, BorderLayout.WEST);
this.add(panel2, BorderLayout.EAST);
}
public void paint(Graphics g){
if(this.isSquare()){
Dimension d = this.getSize();
if(d.height > d.width){
this.setSize(d.width, d.width);
} else {
this.setSize(d.height, d.height);
}
super.paint(g);
}
}
private boolean isSquare() {
return isSquare;
}
private void setSquare(boolean isSquare) {
this.isSquare = isSquare;
}
}
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class SoSquare {
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
// the GUI as seen by the user (without frame)
// A single component added to a GBL with no constraint
// will be centered.
JPanel gui = new JPanel(new GridBagLayout());
gui.setBackground(Color.WHITE);
SquarePanel p = new SquarePanel();
p.setBackground(Color.red);
gui.add(p);
JFrame f = new JFrame("Demo");
f.add(gui);
// Ensures JVM closes after frame(s) closed and
// all non-daemon threads are finished
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// See http://stackoverflow.com/a/7143398/418556 for demo.
f.setLocationByPlatform(true);
// ensures the frame is the minimum size it needs to be
// in order display the components within it
f.pack();
f.setSize(400,100);
// should be done last, to avoid flickering, moving,
// resizing artifacts.
f.setVisible(true);
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
SwingUtilities.invokeLater(r);
}
}
/**
* A square panel for rendering. NOTE: To work correctly, this must be the only
* component in a parent with a layout that allows the child to decide the size.
*/
class SquarePanel extends JPanel {
#Override
public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
Container c = getParent();
if (c != null) {
d = c.getSize();
} else {
return new Dimension(10, 10);
}
int w = (int) d.getWidth();
int h = (int) d.getHeight();
int s = (w < h ? w : h);
return new Dimension(s, s);
}
}
Take advantage of a layout manager that respect the preferred/min/max size of a component. Override the getPreferred/Minimum/MaximumSize methods to return the size you want.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
public class SqaurePaneTest {
public static void main(String[] args) {
new SqaurePaneTest();
}
public SqaurePaneTest() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new BorderLayout());
add(new JLabel("Look ma, I'm a square", JLabel.CENTER));
setBorder(new LineBorder(Color.GRAY));
}
#Override
public Dimension getMinimumSize() {
return getPreferredSize();
}
#Override
public Dimension getMaximumSize() {
return getPreferredSize();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
Alternatively, create your own layout manager that does the same thing (makes all the components square)
I have a button that inserts an unordered list item into a JTextPane. However, when I click on the button to insert a list item, two bullets are inserted instead of one. One bullet is inserted only during the first time insertion.
I cut out the functionality from my application and pasted the code into a small SSCCE (below) and the problem remains. Does anyone have any idea as to what might be happening here?
[The problem has been solved, below is the complete solved code. There are two ways to do this, refer to the functionality in the show and the bullets button]
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.Element;
import javax.swing.text.ElementIterator;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
public class Main {
private static Button2 show = new Button2 ("Show");
private static LIButton bullets = new LIButton("Bullets", HTML.Tag.UL);
private static JEditorPane pane = new JEditorPane();
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
create();
}
});
}
private static void create() throws HeadlessException {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pane.setPreferredSize(new Dimension(300, 300));
pane.setContentType("text/html");
frame.add(pane, BorderLayout.CENTER);
JPanel panel = new JPanel();
panel.add(bullets);
panel.add(show);
frame.add(panel, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
static class LIButton extends JButton {
static final String LI_HTML = "<HTML><BODY><UL><LI></LI></UL></BODY></HTML>";
public LIButton(String name, HTML.Tag parent) {
super(new HTMLEditorKit.InsertHTMLTextAction(
name, LI_HTML, HTML.Tag.UL, HTML.Tag.LI, HTML.Tag.BODY, HTML.Tag.UL));
}
}
static class Button2 extends JButton implements ActionListener {
static final String LI_HTML = "<HTML><BODY><UL><LI></LI></UL></BODY></HTML>";
public Button2(String name) {
super(name);
this.addActionListener(this);
}
#Override
public void actionPerformed(ActionEvent ae) {
HTMLDocument doc = (HTMLDocument) pane.getDocument();
HTMLEditorKit kit = (HTMLEditorKit) pane.getEditorKit();
try {
kit.insertHTML(doc, doc.getLength() - 1, LI_HTML, 0, 1, null);
} catch (BadLocationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
The example below seems to work.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.HeadlessException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLEditorKit;
public class Main {
private static LIButton bullets = new LIButton("Bullets", HTML.Tag.UL);
private static JTextPane pane = new JTextPane();
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
create();
}
});
}
private static void create() throws HeadlessException {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pane.setPreferredSize(new Dimension(300, 300));
pane.setContentType("text/html");
pane.setText("<HTML><BODY><UL></UL></BODY></HTML>");
frame.add(pane, BorderLayout.CENTER);
JPanel panel = new JPanel();
panel.add(bullets);
frame.add(panel, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
static class LIButton extends JButton {
static final String LI_HTML = "<LI>item</LI>";
public LIButton(String name, HTML.Tag parent) {
super(new HTMLEditorKit.InsertHTMLTextAction(
name, LI_HTML, parent, HTML.Tag.LI));
}
}
}