Custom JTabbedPane - java

I want to modify the code of the class AquaBarTabbedPaneUI to work with LEFT tab placements.
JTabbedPane can be cutomized using the BasicTabbedPaneUI.
All that you need it do is write your own UI delegate class extending the BasicTabbedPaneUI class
public class MyTabbedPaneUI extends BasicTabbedPaneUI
{ }
I tried this BasicTabbedPaneUI implementation
import javax.swing.*;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicTabbedPaneUI;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
public class AquaBarTabbedPaneUI extends BasicTabbedPaneUI {
private static final Insets NO_INSETS = new Insets(0, 0, 0, 0);
private ColorSet selectedColorSet;
private ColorSet defaultColorSet;
private ColorSet hoverColorSet;
private boolean contentTopBorderDrawn = true;
private Color lineColor = new Color(158, 158, 158);
private Color dividerColor = new Color(200, 200, 200);
private Insets contentInsets = new Insets(10, 10, 10, 10);
private int lastRollOverTab = -1;
public static ComponentUI createUI(JComponent c) {
return new AquaBarTabbedPaneUI();
}
public AquaBarTabbedPaneUI() {
selectedColorSet = new ColorSet();
selectedColorSet.topGradColor1 = new Color(233, 237, 248);
selectedColorSet.topGradColor2 = new Color(158, 199, 240);
selectedColorSet.bottomGradColor1 = new Color(112, 173, 239);
selectedColorSet.bottomGradColor2 = new Color(183, 244, 253);
defaultColorSet = new ColorSet();
defaultColorSet.topGradColor1 = new Color(253, 253, 253);
defaultColorSet.topGradColor2 = new Color(237, 237, 237);
defaultColorSet.bottomGradColor1 = new Color(222, 222, 222);
defaultColorSet.bottomGradColor2 = new Color(255, 255, 255);
hoverColorSet = new ColorSet();
hoverColorSet.topGradColor1 = new Color(244, 244, 244);
hoverColorSet.topGradColor2 = new Color(223, 223, 223);
hoverColorSet.bottomGradColor1 = new Color(211, 211, 211);
hoverColorSet.bottomGradColor2 = new Color(235, 235, 235);
maxTabHeight = 20;
setContentInsets(0);
}
public void setContentTopBorderDrawn(boolean b) {
contentTopBorderDrawn = b;
}
public void setContentInsets(Insets i) {
contentInsets = i;
}
public void setContentInsets(int i) {
contentInsets = new Insets(i, i, i, i);
}
public int getTabRunCount(JTabbedPane pane) {
return 1;
}
protected void installDefaults() {
super.installDefaults();
RollOverListener l = new RollOverListener();
tabPane.addMouseListener(l);
tabPane.addMouseMotionListener(l);
tabAreaInsets = NO_INSETS;
tabInsets = new Insets(0, 0, 0, 1);
}
protected boolean scrollableTabLayoutEnabled() {
return false;
}
protected Insets getContentBorderInsets(int tabPlacement) {
return contentInsets;
}
protected int calculateTabHeight(int tabPlacement, int tabIndex,
int fontHeight) {
return 21;
}
protected int calculateTabWidth(int tabPlacement, int tabIndex,
FontMetrics metrics) {
int w = super.calculateTabWidth(tabPlacement, tabIndex, metrics);
int wid = metrics.charWidth('M');
w += wid * 2;
return w;
}
protected int calculateMaxTabHeight(int tabPlacement) {
return 21;
}
protected void paintTabArea(Graphics g, int tabPlacement, int selectedIndex) {
Graphics2D g2d = (Graphics2D) g;
g2d.setPaint(new GradientPaint(0, 0, defaultColorSet.topGradColor1, 0,
10, defaultColorSet.topGradColor2));
g2d.fillRect(0, 0, tabPane.getWidth(), 10);
g2d.setPaint(new GradientPaint(0, 10, defaultColorSet.bottomGradColor1,
0, 21, defaultColorSet.bottomGradColor2));
g2d.fillRect(0, 10, tabPane.getWidth(), 11);
super.paintTabArea(g, tabPlacement, selectedIndex);
if (contentTopBorderDrawn) {
g2d.setColor(lineColor);
g2d.drawLine(0, 20, tabPane.getWidth() - 1, 20);
}
}
protected void paintTabBackground(Graphics g, int tabPlacement,
int tabIndex, int x, int y, int w, int h, boolean isSelected) {
Graphics2D g2d = (Graphics2D) g;
ColorSet colorSet;
Rectangle rect = rects[tabIndex];
if (isSelected) {
colorSet = selectedColorSet;
} else if (getRolloverTab() == tabIndex) {
colorSet = hoverColorSet;
} else {
colorSet = defaultColorSet;
}
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int width = rect.width;
int xpos = rect.x;
if (tabIndex > 0) {
width--;
xpos++;
}
g2d.setPaint(new GradientPaint(xpos, 0, colorSet.topGradColor1, xpos,
10, colorSet.topGradColor2));
g2d.fillRect(xpos, 0, width, 10);
g2d.setPaint(new GradientPaint(0, 10, colorSet.bottomGradColor1, 0, 21,
colorSet.bottomGradColor2));
g2d.fillRect(xpos, 10, width, 11);
if (contentTopBorderDrawn) {
g2d.setColor(lineColor);
g2d.drawLine(rect.x, 20, rect.x + rect.width - 1, 20);
}
}
protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex,
int x, int y, int w, int h, boolean isSelected) {
Rectangle rect = getTabBounds(tabIndex, new Rectangle(x, y, w, h));
g.setColor(dividerColor);
g.drawLine(rect.x + rect.width, 0, rect.x + rect.width, 20);
}
protected void paintContentBorderTopEdge(Graphics g, int tabPlacement,
int selectedIndex, int x, int y, int w, int h) {
}
protected void paintContentBorderRightEdge(Graphics g, int tabPlacement,
int selectedIndex, int x, int y, int w, int h) {
// Do nothing
}
protected void paintContentBorderLeftEdge(Graphics g, int tabPlacement,
int selectedIndex, int x, int y, int w, int h) {
// Do nothing
}
protected void paintContentBorderBottomEdge(Graphics g, int tabPlacement,
int selectedIndex, int x, int y, int w, int h) {
// Do nothing
}
protected void paintFocusIndicator(Graphics g, int tabPlacement,
Rectangle[] rects, int tabIndex, Rectangle iconRect,
Rectangle textRect, boolean isSelected) {
// Do nothing
}
protected int getTabLabelShiftY(int tabPlacement, int tabIndex,
boolean isSelected) {
return 0;
}
private class ColorSet {
Color topGradColor1;
Color topGradColor2;
Color bottomGradColor1;
Color bottomGradColor2;
}
private class RollOverListener implements MouseMotionListener,
MouseListener {
public void mouseDragged(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
checkRollOver();
}
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
checkRollOver();
}
public void mouseExited(MouseEvent e) {
tabPane.repaint();
}
private void checkRollOver() {
int currentRollOver = getRolloverTab();
if (currentRollOver != lastRollOverTab) {
lastRollOverTab = currentRollOver;
Rectangle tabsRect = new Rectangle(0, 0, tabPane.getWidth(), 20);
tabPane.repaint(tabsRect);
}
}
}
}
to customize my JTabbedPane
JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.setUI(new AquaBarTabbedPaneUI());
I get this
Sadly, most of the tabbed pane UI delegates work correctly only when the tab placement is set to TOP. The code needs to be tweaked in order for it to work with all tab placements (LEFT, RIGHT, BOTTOM)

Related

paintComponent overwrites pixels

So I've added a grid to my BufferedImage, by doing it in the PaintComponentlike this. It works perfect.
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
Color c=new Color(184, 184, 184, 255);
g.drawImage(canvas, 0, 0, this);
for ( int x = 0; x <= getWidth(); x += 10 ){
for ( int y = 0; y <= getHeight(); y += 10 ){
g.setColor(c);
g.drawRect( x, y, 10, 10 );
}
}
}
BUT, when I then draw my line/circles in this function:
public void drawPixels(Object val_x, Boolean highlight)
{
String[] values = val_x.toString().replaceAll("[()]", "").split(",");
if (highlight){
canvas.setRGB(Integer.parseInt(values[0]), Integer.parseInt(values[1]), Color.RED.getRGB());
}else{
canvas.setRGB(Integer.parseInt(values[0]), Integer.parseInt(values[1]), c.getRGB());
}
repaint();
}
I see that some of my pixels is overwriten by the grid from paintComponent.
Is there a way to z-index the grid behind the pixels I draw, or maybe draw the grid first, and then draw on the top of that?
My GUI looks like this, where you can see that my circles pixels is swapped with the grid:
If you want to look at the whole drawing .java file
package DrawCanvas;
import com.sun.org.apache.xpath.internal.operations.Bool;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
public class DrawCanvas extends JPanel {
private BufferedImage canvas;
private static Graphics g2;
final private Color c = Color.BLACK;
private final static Color def_bg = new Color(108, 108, 108, 255);
//private final static Color def_bg = new Color(80, 80, 80, 255);
int width = 1280;
int height = 720;
public DrawCanvas() {
canvas = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
g2 = canvas.getGraphics();
fillCanvas(def_bg);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(canvas.getWidth(), canvas.getHeight());
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
Color c=new Color(184, 184, 184, 255);
g.drawImage(canvas, 0, 0, this);
for ( int x = 0; x <= getWidth(); x += 10 ){
for ( int y = 0; y <= getHeight(); y += 10 ){
g.setColor(c);
g.drawRect( x, y, 10, 10 );
}
}
}
public void fillCanvas(Color c) {
int color = c.getRGB();
for (int x = 0; x < canvas.getWidth(); x++) {
for (int y = 0; y < canvas.getHeight(); y++) {
canvas.setRGB(x, y, color);
}
}
repaint();
}
// Implementation from Wikipedia: https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm#All_cases
public void drawPixels(Object val_x, Boolean highlight)
{
String[] values = val_x.toString().replaceAll("[()]", "").split(",");
if (highlight){
canvas.setRGB(Integer.parseInt(values[0]), Integer.parseInt(values[1]), Color.RED.getRGB());
}else{
canvas.setRGB(Integer.parseInt(values[0]), Integer.parseInt(values[1]), c.getRGB());
}
repaint();
}
public void clearImage() {
Graphics2D g2 = (Graphics2D) canvas.getGraphics();
g2.setBackground(def_bg);
g2.clearRect(0,0, (int)canvas.getWidth(), (int)canvas.getHeight());
repaint();
}
}
EDIT 1 solution
package DrawCanvas;
import com.sun.org.apache.xpath.internal.operations.Bool;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
public class DrawCanvas extends JPanel {
private BufferedImage canvas;
private static Graphics g2;
final private Color c = Color.BLACK;
private final static Color def_bg = new Color(108, 108, 108, 255);
private final static Color grid = new Color(149, 149, 149, 186);
//private final static Color def_bg = new Color(80, 80, 80, 255);
int width = 1280;
int height = 720;
public DrawCanvas() {
canvas = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
g2 = canvas.getGraphics();
fillCanvas(def_bg);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(canvas.getWidth(), canvas.getHeight());
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.drawImage(canvas, 0, 0, this);
}
public void fillCanvas(Color c) {
int color = c.getRGB();
for (int x = 0; x < canvas.getWidth(); x++) {
for (int y = 0; y < canvas.getHeight(); y++) {
canvas.setRGB(x, y, color);
}
}
drawGrid();
repaint();
}
// Implementation from Wikipedia: https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm#All_cases
// Implementation from Wikipedia: https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm#All_cases
public void drawPixels(Object val_x, Boolean highlight)
{
Graphics2D graph = canvas.createGraphics();
String[] values = val_x.toString().replaceAll("[()]", "").split(",");
if (highlight){
graph.setColor(Color.RED);
graph.drawOval(Integer.parseInt(values[0]), Integer.parseInt(values[1]), 1, 1);
}else{
graph.setColor(c);
graph.drawOval(Integer.parseInt(values[0]), Integer.parseInt(values[1]), 1, 1);
}
}
public void drawGrid(){
Graphics2D graph = canvas.createGraphics();
for (int x = 0; x < canvas.getWidth(); x += 10) {
for (int y = 0; y < canvas.getHeight(); y += 10) {
graph.setColor(grid);
graph.drawRect( x, y, 10, 10 );
}
}
repaint();
}
public void clearImage() {
Graphics2D g2 = (Graphics2D) canvas.getGraphics();
g2.setBackground(def_bg);
g2.clearRect(0,0, (int)canvas.getWidth(), (int)canvas.getHeight());
drawGrid();
repaint();
}
}

Grid drawn on A JPanel is not visible completely

I have a panel which extends JPanel and overrides method paintComponent(Graphics g) which draw some squares.
public class Painter extends JPanel{
private static final Color orange = new Color(225, 95, 0);
private Block[][] blocks;
private int sizeBlock;
public Painter() {
this.setBackground(Color.WHITE);
}
public void setBlocks(Block[][] blocks) {
this.blocks = blocks;
}
public void setSizeBlock(int size) {
this.sizeBlock = size;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
for(Block[] cols : blocks) {
for(Block block : cols) {
switch(block.getType()) {
case Block.wall: {
paintBlockLineBorder(g, block.getX()*(sizeBlock-1),
block.getY()*(sizeBlock-1), orange);
break;
}
default: {break;}
}
}
}
}
private void paintBlockLineBorder(Graphics g, int x, int y, Color color) {
//background
g.setColor(color);
g.fillRect(x, y, sizeBlock, sizeBlock);
//border
g.setColor(Color.BLACK);
g.drawRect(x, y, sizeBlock-1, sizeBlock-1);
}
}
I add this JPanel (Painter) into other JPanel (painterPanel) which is added to a JFrame with layout GridBagLayout.
The result is not how I want:
This is what I want:
Here is a little use-case which reproduces the problem:
public static void main(String[] args) {
JFrame mainFrame = new JFrame();
mainFrame.setLayout(new GridBagLayout());
mainFrame.setBounds(100, 100, 500, 400);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.fill = GridBagConstraints.NONE;
gbc.gridx = 0; gbc.gridy = 0;
gbc.weighty = 1; gbc.weightx = 1;
JPanel painterPanel = new JPanel();
painterPanel.setBorder(BorderFactory.createLineBorder(Color.black));
mainFrame.add(painterPanel, gbc);
Painter apainter = new Painter();
painterPanel.add(apainter);
Block[][] ablock = new Block[2][2];
ablock[0][0] = new Block(0, 0, Block.wall);
ablock[0][1] = new Block(0, 1, Block.wall);
ablock[1][0] = new Block(1, 0, Block.wall);
ablock[1][1] = new Block(1, 1, Block.wall);
apainter.setBlocks(ablock);
apainter.setSizeBlock(25);
apainter.repaint();
mainFrame.setVisible(true);
}
and here is Block class:
public class Block {
public static final String wall = "wall";
private int x;
private int y;
private String type;
public Block(int x, int y, String type) {
this.x = x;
this.y = y;
this.type = type;
}
//getters & setters
}
Why is my Painter not completely visible?
Try the following :
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main{
public static void main(String[] args) throws InterruptedException{
JFrame mainFrame = new JFrame();
Block[][] ablock = new Block[2][2];
ablock[0][0] = new Block(0, 0, Block.wall);
ablock[0][1] = new Block(0, 1, Block.wall);
ablock[1][0] = new Block(1, 0, Block.wall);
ablock[1][1] = new Block(1, 1, Block.wall);
Painter apainter = new Painter();
mainFrame.add(apainter);
apainter.setBlocks(ablock);
apainter.setSizeBlock(25);
mainFrame.pack();
mainFrame.setVisible(true);
}
}
class Painter extends JPanel{
private static final Color orange = new Color(225, 95, 0);
private Block[][] blocks;
private int sizeBlock;
public Painter() {
setBackground(Color.WHITE);
setBorder(BorderFactory.createLineBorder(Color.black));
setPreferredSize(new Dimension(400, 300));
}
public void setBlocks(Block[][] blocks) {
this.blocks = blocks;
}
public void setSizeBlock(int size) {
sizeBlock = size;
//you may want to update Preferred Size
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
for(Block[] cols : blocks) {
for(Block block : cols) {
switch(block.getType()) {
case Block.wall: {
paintBlockLineBorder(g, block.getX()*(sizeBlock-1),
block.getY()*(sizeBlock-1), orange);
break;
}
default: {break;}
}
}
}
}
private void paintBlockLineBorder(Graphics g, int x, int y, Color color) {
//background
g.setColor(color);
g.fillRect(x, y, sizeBlock, sizeBlock);
//border
g.setColor(Color.BLACK);
g.drawRect(x, y, sizeBlock-1, sizeBlock-1);
}
}
class Block {
public static final String wall = "wall";
private final int x;
private final int y;
private final String type;
public Block(int x, int y, String type) {
this.x = x;
this.y = y;
this.type = type;
}
int getX() {return x; }
int getY() {return y; }
String getType() { return type;}
}
Don't hesitate to ask for clarifications as needed.
Also consider making a grid using GridLayout : 1 2
At advice of #CarlosHeuberger I overrided getPreferredSize, getMinimumSize and getMaximumSize which return a Dimension with values based on lengths of blocks and value of sizeBlock

JTabbedPane Tab unselected does not fill JPanel while selected does

I have custom JTabbedPane, I am having issue with making the tabs the same size as each other.
as you can see in the image, The green tab is selected, while the Red is unselected, I would like the Red Tab (Unselected) to be the same size as the Green Tab (Selected) here is my code
here is the code.
import javax.swing.*;
import javax.swing.plaf.basic.BasicTabbedPaneUI;
import java.awt.*;
public class UITest {
public static void main(String[] args){
JFrame jFrame = new JFrame();
JTabbedPane jTabbedPane = new JTabbedPane();
jTabbedPane.add(new JPanel(), "test");
jTabbedPane.add(new JPanel(), "test2");
jTabbedPane.setUI(new LynxTabbedPane());
jFrame.setContentPane(jTabbedPane);
jFrame.setSize(200,200);
jFrame.setVisible(true);
}
public static class LynxTabbedPane extends BasicTabbedPaneUI {
private Polygon shape;
#Override
protected void paintTabBackground(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected) {
Graphics2D g2D = (Graphics2D) g;
int xp[] = new int[]{x, x, x + w, x + w, x};
int yp[] = new int[]{y, y + h, y + h, y, y};
shape = new Polygon(xp, yp, xp.length);
if (isSelected) {
g2D.setColor(Color.GREEN);
} else if (tabPane.isEnabled() && tabPane.isEnabledAt(tabIndex)) {
g2D.setColor(Color.RED);
}
g2D.fill(shape);
}
}
}
I have fixed the issue by moving g2D.fill(shape); inside isSelected
#Override
protected void paintTabBackground(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected) {
Graphics2D g2D = (Graphics2D) g;
int xp[] = new int[]{x, x, x + w, x + w, x};
int yp[] = new int[]{y, y + h, y + h, y, y};
shape = new Polygon(xp, yp, xp.length);
if (isSelected) {
g2D.fill(shape);
g2D.setColor(selectColor);
} else if (tabPane.isEnabled() && tabPane.isEnabledAt(tabIndex)) {
g2D.setColor(deSelectColor);
}
}
This will only fill it with the shape if the tab is selected.
Result:

Custom Java Component Not Drawn Correctly

I have a custom button that is not being drawn properly. It shows up as a dot in the upper left hand corner. I have three classes. One for the button, one for the menu or drawing of several buttons and a main class that calls the menu.
Class 1 - button
#Override
protected void paintComponent(Graphics g) {
g.setColor(Color.white);
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(img, this.x, this.y,this.getWidth(), this.getHeight(), null);
g2d.setFont(this.font);
g2d.drawString(this.label, x, y);
}
Class 2 - menu
public void draw(Graphics g, int width, int height) {
int x, y;
for(int i = 0; i < buttons.length; i++) {
x = (int) (width / 2 - buttons[i].getWidth() / 2);
y = (int) (height / 2 - buttons[i].getHeight() / 2);
buttons[i].setBounds(x, y + (i*60), buttons[i].getWidth(), buttons[i].getHeight());
buttons[i].paintComponent(g);
}
}
Class 3 - main
if(gMenu != null) {
gMenu.draw(g, gWindow.getWidth(), gWindow.getHeight());
}
Edit: To clarify what I'm trying to do is create a popup menu with a few custom buttons (components).
Edit: I got them to draw, but the mouse listener doesn't work.
here is the menu class
public class Menu extends JComponent {
GameWindow window;
public Menu(GameWindow window) {
this.window = window;
this.setVisible(true);
}
public void addChildToPanel(JComponent child) {
int width = (int) getWidth();
if(child.getWidth() > width) {
width = child.getWidth();
}
int height = (int) getHeight();
height += child.getHeight();
setSize(width, height);
Dimension screen = new Dimension(window.getWidth(), window.getHeight());
int x = (screen.width - width) / 2;
int y = (screen.height - height) / 2;
setBounds(x, y, width, height);
}
}
Here is the button class
public class MenuButton extends JComponent implements MouseListener {
private BufferedImage img;
private BufferedImage img_h;
private int x, y;
private String label;
private Font font;
private int state = 0;
// state 0 = normal
// state 1 = highlight
// state 2 = pressed
public MenuButton(BufferedImage img, BufferedImage img_h, String label, Font font) {
this.setPreferredSize(new Dimension(img.getWidth(), img.getHeight()));
this.img_h = img_h;
this.img = img;
this.label = label;
this.font = font;
setVisible(true);
setBounds(0, 0, img.getWidth(), img.getHeight());
this.addMouseListener(this);
}
#Override
protected void paintComponent(Graphics g) {
g.setColor(Color.white);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
switch (state) {
case 0:
g2d.drawImage(img, this.getBounds().x, this.getBounds().y,this.getWidth(), this.getHeight(), null);
break;
case 1:
g2d.drawImage(img_h, this.getBounds().x, this.getBounds().y,this.getWidth(), this.getHeight(), null);
break;
case 2:
g2d.drawImage(img, this.x, this.y,this.getWidth(), this.getHeight(), null);
break;
}
g2d.setFont(this.font);
int size = g2d.getFontMetrics(font).stringWidth(this.label);
int x = this.getBounds().x + this.getWidth() - 20 - size;
int y = this.getBounds().y + 29;
g2d.drawString(this.label,x, y);
}
public void setState(int state) {
this.state = state;
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
setState(1);
}
#Override
public void mouseExited(MouseEvent e) {
setState(0);
}
#Override
public void mousePressed(MouseEvent e) {
setState(2);
}
#Override
public void mouseReleased(MouseEvent e) {
setState(1);
}
}
Child class that I call draw on
public class PauseMenu extends Menu {
private int width;
private int height;
private MenuButton[] buttons = new MenuButton[4];
public PauseMenu(GameWindow window) {
super(window);
Font font = null;
BufferedImage img = null;
BufferedImage img_h = null;
try {
InputStream is = getClass().getResourceAsStream("/fonts/ALDOPC.ttf");
font = Font.createFont(Font.TRUETYPE_FONT, is).deriveFont(Font.PLAIN, 24f);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont(font);
img = ImageIO.read(getClass().getResourceAsStream("/gui/bg_menu_button_round.png"));
img_h = ImageIO.read(getClass().getResourceAsStream("/gui/bg_menu_button_round_highlight.png"));
}
catch(Exception e)
{
System.out.print("Failed to load resources");
System.out.println();
}
MenuButton resume = new MenuButton(img, img_h, "CONTINUE", font);
final MenuButton quit = new MenuButton(img, img_h, "QUIT", font);
MenuButton vid = new MenuButton(img, img_h, "VIDEO", font);
MenuButton sound = new MenuButton(img, img_h, "SOUND", font);
buttons[0] = resume;
buttons[1] = vid;
buttons[2] = sound;
buttons[3] = quit;
for(int i = 0; i < buttons.length; i++) {
int x = (window.getWidth() - img.getWidth()) / 2;
int y = (window.getHeight() - img.getHeight()) / 2;
buttons[i].setBounds(x, y + (i * img.getHeight()), img.getWidth(), img.getHeight());
this.addChildToPanel(buttons[i]);
}
}
public void draw(Graphics g) {
for(int i = 0; i < buttons.length; i++)
buttons[i].paintComponent(g);
}
}

How to set a 3D border for a JDialog with rounded corners?

I could add a rounded corner border to my JDialog as in How to create a rounded title border in Java Swing. But it is still one color. I want to make the border looks like 3D.
Here is how I tried.
Graphics2D g2d = (Graphics2D) g;
Color c1 = getBackground();
Color c2 = color1.darker();
int w = getWidth();
int h = getHeight();
GradientPaint gp = new GradientPaint(
0, 0, c1,
0, h, c2);
g2d.setPaint(gp);
g2d.fill3DRect(0,0, w, h,true);
Then, no 3D look, but the border has been widen more with its border color.
How can I achieve this?
Any sample code or links will be highly appreciated.
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import javax.swing.border.*;
public class ThreeDimensionalBorder extends AbstractBorder {
private static final long serialVersionUID = 1L;
private Color color;
private int thickness = 8;
private int radii = 8;
private Insets insets = null;
private BasicStroke stroke = null;
private int strokePad;
RenderingHints hints;
int shadowPad = 3;
ThreeDimensionalBorder(Color color) {
this(color, 128, 8);
}
ThreeDimensionalBorder(Color color, int transparency, int shadowWidth) {
this.color = color;
shadowPad = shadowWidth;
stroke = new BasicStroke(thickness);
strokePad = thickness/2;
hints = new RenderingHints(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int pad = radii + strokePad;
int bottomPad = pad + strokePad + shadowPad;
int rightPad = pad + strokePad + shadowPad;
insets = new Insets(pad,pad,bottomPad+shadowPad,rightPad);
}
#Override
public Insets getBorderInsets(Component c) {
return insets;
}
#Override
public Insets getBorderInsets(Component c, Insets insets) {
return getBorderInsets(c);
}
#Override
public void paintBorder(
Component c,
Graphics g,
int x, int y,
int width, int height) {
Graphics2D g2 = (Graphics2D)g;
int bottomLineY = height-thickness-shadowPad;
RoundRectangle2D.Double bubble = new RoundRectangle2D.Double(
0+strokePad,
0+strokePad,
width-thickness-shadowPad,
bottomLineY,
radii,
radii
);
Area area = new Area(bubble);
g2.setRenderingHints(hints);
g2.setColor(color);
g2.setStroke(stroke);
g2.draw(area);
Area shadowArea = new Area(new Rectangle(0,0,width,height));
shadowArea.subtract(area);
g.setClip(shadowArea);
Color shadow = new Color(color.getRed(),color.getGreen(),color.getBlue(),128);
g2.setColor(shadow);
g2.translate(shadowPad,shadowPad);
g2.draw(area);
AffineTransform at = g2.getTransform();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JPanel p = new JPanel();
String t = "The quick brown fox jumps over the lazy dog!";
JLabel l1 = new JLabel(t);
l1.setBorder(new ThreeDimensionalBorder(Color.MAGENTA.darker(),128,4));
p.add(l1);
JLabel l2 = new JLabel(t);
l2.setBorder(new ThreeDimensionalBorder(Color.BLACK,200,5));
p.add(l2);
JLabel l3 = new JLabel(t);
l3.setBorder(new ThreeDimensionalBorder(Color.BLUE,40,6));
p.add(l3);
JOptionPane.showMessageDialog(null, p);
}
});
}
}
Would this suffice??
It's far from perfect, but the basic idea works...
public class MyRoundedBorder implements Border {
protected static final Insets DEFAULT_INSETS = new Insets(4, 4, 4, 4);
#Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setStroke(new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
g2d.setColor(Color.WHITE);
Shape corner = new RoundedShape(width - 8, height - 8);
g2d.translate(x + 2, y + 2);
g2d.draw(corner);
g2d.transform(AffineTransform.getRotateInstance(Math.toRadians(180), (width - 8) / 2, (height - 8) / 2));
g2d.setColor(Color.LIGHT_GRAY);
g2d.draw(corner);
g2d.dispose();
}
#Override
public Insets getBorderInsets(Component c) {
return DEFAULT_INSETS;
}
#Override
public boolean isBorderOpaque() {
return true;
}
public class RoundedShape extends Path2D.Float {
public RoundedShape(int width, int height) {
moveTo(0, height - 20);
append(new Arc2D.Float(0, height - 20, 20, 20, 180, 45, Arc2D.CHORD), false);
lineTo(0, 20);
curveTo(0, 0, 0, 0, 20, 0);
lineTo(width - 10, 0);
append(new Arc2D.Float(width - 20, 0, 20, 20, 90, -45, Arc2D.CHORD), false);
}
}
}

Categories