My partner and I are trying to remake Tetris for our final project of the year in my Computer Science class we currently have a for loop that draws individual rectangles in an overwritten paint method.
private final int spacer = 30;
public int getSpacer()
{
return spacer;
}
public void paint(Graphics g) {
setBackground(Color.GRAY);
for(int i = getHeight()/2 - (spacer * 10); i < getHeight()/2 + (spacer * 10); i += spacer) {
for(int x = getWidth()/2 - (spacer * 5); x < getWidth()/2 + (spacer * 5); x += (spacer)) {
g.drawRect(x, i, (spacer), (spacer));
}
}
setForeground(Color.black);
}
The method basically takes the width and height of the window and makes a 10 x 20 grid of boxes that are 30 units, pixels I think, wide.
We'd like to make a Grid.java class that takes in color, the spacer int, and an x and y int. The constructor for Grid.java should draw the exact same thing as the code above using the for loop, but when we tried it gave us a white screen that would not resize with the window.
private final int spacer = 30;
private static Grid[][] arr = new Grid[10][20];
public int getSpacer()
{
return spacer;
}
public void paint(Graphics g) {
setBackground(Color.GRAY);
int countY = 0;
int countX = 0;
for(int y = getHeight()/2 - (spacer * 10); y < getHeight()/2 + (spacer * 10); y += spacer) {
for(int x = getWidth()/2 - (spacer * 5); x < getWidth()/2 + (spacer * 5); x += spacer) {
arr[countX][countY] = new Grid(x, y, spacer, g);
countX++;
}
countY++;
}
setForeground(Color.black);
}
*Grid.java Class*
package Tetris_Shapes;
import javax.swing.*;
import java.awt.*;
public class Grid {
private int x;
private int y;
private int side;
private Graphics g;
public Grid(int x, int y, int side, Graphics g) {
// g.drawRect(x, y, spacer, spacer);
this.x = x;
this.y = y;
this.side = side;
this.g = g;
paint(this.g);
}
private void paint(Graphics g) {
g.drawRect(x, y, side, side);
}
}
When we try and run this we get the white box that doesn't resize. My question is does anyone know of a way to get a constructor to draw shapes. Thank you in advance, this is pretty niche so I'm also going to apologize in advance.
How can I create a JButton like this with inner shadow in Swing?
I wan to create JButton with different Color of border, like top and left border color should be black and right and bottom border color should be of white color.
But all together, I want inner shadow of dark gray color in top and left side like above image.
First I thought you can just achieve this with a simple BevelBorder, but unfortunately you can't set the border's thickness comfortably... So I had to basically make a customized Border. You can customize it more if you don't like the style of my button in the paintBorder method, but you have to know how to work with Graphics. Here is what I've got:
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.border.Border;
/**
*
*/
public class MyBorder implements Border {
private int thickness_ = 4;
private Color white = Color.WHITE;
private Color gray = Color.GRAY;
private Color black = Color.BLACK;
public static void main(String[] args) {
JFrame frm = new JFrame("Border Test");
frm.setLayout(new FlowLayout());
JButton btn = new JButton("Button");
MyBorder border = new MyBorder();
btn.setBorder(border);
btn.setFocusPainted(false);
btn.setPreferredSize(new Dimension(60,30));
btn.setBackground(Color.LIGHT_GRAY);
frm.add(btn);
frm.setSize(200,200);
frm.setVisible(true);
}
public void paintBorder(Component c, Graphics g, int x, int y, int width,
int height) {
Color oldColor = g.getColor();
int i;
for (i = 0; i < thickness_; i++) {
g.setColor(white);
g.drawRect(x + i, y + i, width - i - i - 1, height - i - i - 1); //White Rectangle
}
for (i = 0; i < thickness_/2; i++) {
g.setColor(black);
g.drawLine(x + i, y + i, (width - x) - (i * 2), y + i); //Top Outer Edge
g.drawLine(x + i, y + i, x + i, (height - y) - (i * 2)); //Left Outer Edge
}
for (i = thickness_/2; i < thickness_; i++) {
g.setColor(gray);
g.drawLine(x + i, y + i, (width - x) - (i * 2), y + i); //Top Inner Edge
g.drawLine(x + i, y + i, x + i, (height - y) - (i * 2)); //Left Inner Edge
}
g.setColor(oldColor);
}
public int getThickness() {
return thickness_;
}
public void setThickness(int i) {
thickness_ = i;
}
public boolean isBorderOpaque() {
return true;
}
public Insets getBorderInsets(Component c) {
return new Insets(thickness_, thickness_, thickness_, thickness_);
}
}
I am trying to make a bar chart. Everything goes fine; the code compiles and runs successfully. But the frame (window) is not packed perfectly. There is some space at the end of the bar chart. I just want this space removed.
public class BarChart extends JPanel{
int[] percentage;
Color color;
double barOffset;
public BarChart(int[] percentage, Color color) {
this.color = color;
this.percentage = percentage;
}
public BarChart(int[] percentage) {
this.color = Color.black;
this.percentage = percentage;
}
public BarChart() {
this.color = Color.black;
}
int w = 1,h = 1;
protected void paintComponent(Graphics g) {
super.paintComponent(g);
w = getWidth();
h = getHeight();
g.setColor(color);
barOffset = w*0.05;
int barWidth = (int)(w*0.1);
for(int i = 0; i<percentage.length; i++) {
g.fillRect((int)(barOffset),(int)(h*0.95-2*percentage[i]), barWidth, 2*percentage[i]);
if(i < percentage.length-1)
barOffset = (i+2)*w*0.05 + (i+1)*(barWidth);
}
}
}
This was not a packing error, but rather you were drawing off the edge of the component. To check for packing errors, set a background color for the container that is distinct from the component color.
For the set int[] p = new int[]{100, 5, 6, 9, 1, 0, 5, 100};, your bars are being drawn as follows:
component dimensions: width=104 height=10
bar[0]: xLeft=5 yTop=-190 barWidth=10 barHeight=200
bar[1]: xLeft=20 yTop=0 barWidth=10 barHeight=10
bar[2]: xLeft=35 yTop=-2 barWidth=10 barHeight=12
bar[3]: xLeft=50 yTop=-8 barWidth=10 barHeight=18
bar[4]: xLeft=66 yTop=7 barWidth=10 barHeight=2
bar[5]: xLeft=81 yTop=9 barWidth=10 barHeight=0
bar[6]: xLeft=96 yTop=0 barWidth=10 barHeight=10
bar[7]: xLeft=111 yTop=-190 barWidth=10 barHeight=200
I think this produces what you're looking for. Drawing components can be tricky, and the way I mitigate the complexity is to keep track of my screen locations semantically.
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class BarChart extends JPanel
{
public static void main(String[] args)
{
int[] p = new int[]{100, 5, 6, 9, 1, 0, 5, 100};
JFrame f = new JFrame();
f.setBackground(Color.BLUE);
BarChart chart = new BarChart(p);
chart.setBackground(Color.RED);
f.add(chart);
f.pack();
f.show();
}
private int[] percentage;
private Color color;
private boolean padEnds = true;
public BarChart(int[] percentage, Color color)
{
this.percentage = percentage;
this.color = color;
return;
}
public BarChart(int[] percentage)
{
this(percentage, Color.BLACK);
return;
}
public BarChart()
{
this(new int[0]);
return;
}
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(this.color);
int width = super.getWidth();
int height = super.getHeight();
int topPadding = Math.round(height * 0.05f);
int barCount = this.percentage.length;
int barOffset = Math.round(width * 0.025f); // 2.5% (in pixels) reserved space on both sides of each bar == 5% between bars
int totalOffsetWidth = (barOffset * 2) * barCount;
if (!this.padEnds)
{
totalOffsetWidth -= (barOffset * 2);
}
int availableWidth = width - totalOffsetWidth;
int availableHeight = height - topPadding;
int barWidth = (int) Math.floor((float) availableWidth / (float) barCount);
int xLeft = 0;
for (int i = 0; i < barCount; i++)
{
int percent = this.percentage[i];
if (this.padEnds || (i != 0))
{
xLeft += barOffset; // Add offset here to pad left side of each bar.
}
int barHeight = Math.round(((float) availableHeight) * ((float) percent / 100f));
int yTop = topPadding + (availableHeight - barHeight);
g.fillRect(xLeft, yTop, barWidth, barHeight);
xLeft += barWidth; // advance the next drawing position
if (this.padEnds || (i != (barCount - 1)))
{
xLeft += barOffset; // Add offset here to pad right side of each bar.
}
}
return;
}
}
I am trying to change the shape of the tabs in a JTabbedPane. Using setTabComponentAt(0, someComponent); doesn't change the exterior of the tab, which is a rectangle with a diagonal top-left corner. What may be done to change the shape?
correct way is only to change Look and Feel, nice example from Old.Java.Forums.Sun
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
public class TabbedPane extends JPanel {
private static final long serialVersionUID = 1L;
public TabbedPane() {
setLayout(new BorderLayout());
JPanel jp = new JPanel();
jp.setLayout(new BorderLayout());
JTabbedPane tb = new JTabbedPane();
tb.setUI(new CustomTabbedPaneUI());
tb.add("Tab1", new JTextArea(""));
tb.add("Tab2", new JTextArea(""));
tb.add("Tab3", new JTextArea(""));
tb.add("Tab4", new JTextArea(""));
tb.add("Tab5", new JTextArea(""));
jp.add(tb, BorderLayout.CENTER);
add(jp, BorderLayout.CENTER);
tb.setEnabledAt(1, false);
tb.setEnabledAt(3, false);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.getContentPane().add(new TabbedPane());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 200);
frame.setVisible(true);
}
}
and
import java.util.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.plaf.*;
import javax.swing.plaf.basic.*;
import javax.swing.text.View;
public class CustomTabbedPaneUI extends BasicTabbedPaneUI {
private Color selectColor;
private Color deSelectColor;
private int inclTab = 4;
private int anchoFocoV = inclTab;
private int anchoFocoH = 4;
private int anchoCarpetas = 18;
private Polygon shape;
public static ComponentUI createUI(JComponent c) {
return new CustomTabbedPaneUI();
}
#Override
protected void installDefaults() {
super.installDefaults();
selectColor = new Color(250, 192, 192);
deSelectColor = new Color(197, 193, 168);
tabAreaInsets.right = anchoCarpetas;
}
#Override
protected void paintTabArea(Graphics g, int tabPlacement, int selectedIndex) {
if (runCount > 1) {
int lines[] = new int[runCount];
for (int i = 0; i < runCount; i++) {
lines[i] = rects[tabRuns[i]].y + (tabPlacement == TOP ? maxTabHeight : 0);
}
Arrays.sort(lines);
if (tabPlacement == TOP) {
int fila = runCount;
for (int i = 0; i < lines.length - 1; i++, fila--) {
Polygon carp = new Polygon();
carp.addPoint(0, lines[i]);
carp.addPoint(tabPane.getWidth() - 2 * fila - 2, lines[i]);
carp.addPoint(tabPane.getWidth() - 2 * fila, lines[i] + 3);
if (i < lines.length - 2) {
carp.addPoint(tabPane.getWidth() - 2 * fila, lines[i + 1]);
carp.addPoint(0, lines[i + 1]);
} else {
carp.addPoint(tabPane.getWidth() - 2 * fila, lines[i] + rects[selectedIndex].height);
carp.addPoint(0, lines[i] + rects[selectedIndex].height);
}
carp.addPoint(0, lines[i]);
g.setColor(hazAlfa(fila));
g.fillPolygon(carp);
g.setColor(darkShadow.darker());
g.drawPolygon(carp);
}
} else {
int fila = 0;
for (int i = 0; i < lines.length - 1; i++, fila++) {
Polygon carp = new Polygon();
carp.addPoint(0, lines[i]);
carp.addPoint(tabPane.getWidth() - 2 * fila - 1, lines[i]);
carp.addPoint(tabPane.getWidth() - 2 * fila - 1, lines[i + 1] - 3);
carp.addPoint(tabPane.getWidth() - 2 * fila - 3, lines[i + 1]);
carp.addPoint(0, lines[i + 1]);
carp.addPoint(0, lines[i]);
g.setColor(hazAlfa(fila + 2));
g.fillPolygon(carp);
g.setColor(darkShadow.darker());
g.drawPolygon(carp);
}
}
}
super.paintTabArea(g, tabPlacement, selectedIndex);
}
#Override
protected void paintTabBackground(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected) {
Graphics2D g2D = (Graphics2D) g;
GradientPaint gradientShadow;
int xp[] = null; // Para la forma
int yp[] = null;
switch (tabPlacement) {
case LEFT:
xp = new int[]{x, x, x + w, x + w, x};
yp = new int[]{y, y + h - 3, y + h - 3, y, y};
gradientShadow = new GradientPaint(x, y, new Color(100, 100, 255), x, y + h, Color.ORANGE);
break;
case RIGHT:
xp = new int[]{x, x, x + w - 2, x + w - 2, x};
yp = new int[]{y, y + h - 3, y + h - 3, y, y};
gradientShadow = new GradientPaint(x, y, new Color(100, 100, 255), x, y + h, new Color(153, 186, 243));
break;
case BOTTOM:
xp = new int[]{x, x, x + 3, x + w - inclTab - 6, x + w - inclTab - 2, x + w - inclTab, x + w - 3, x};
yp = new int[]{y, y + h - 3, y + h, y + h, y + h - 1, y + h - 3, y, y};
gradientShadow = new GradientPaint(x, y, new Color(100, 100, 255), x, y + h, Color.BLUE);
break;
case TOP:
default:
xp = new int[]{x, x, x + 3, x + w - inclTab - 6, x + w - inclTab - 2, x + w - inclTab, x + w - inclTab, x};
yp = new int[]{y + h, y + 3, y, y, y + 1, y + 3, y + h, y + h};
gradientShadow = new GradientPaint(0, 0, Color.ORANGE, 0, y + h / 2, new Color(240, 255, 210));
break;
}
// ;
shape = new Polygon(xp, yp, xp.length);
if (isSelected) {
g2D.setColor(selectColor);
g2D.setPaint(gradientShadow);
} else {
if (tabPane.isEnabled() && tabPane.isEnabledAt(tabIndex)) {
g2D.setColor(deSelectColor);
GradientPaint gradientShadowTmp = new GradientPaint(0, 0, new Color(255, 255, 200), 0, y + h / 2, new Color(240, 255, 210));
g2D.setPaint(gradientShadowTmp);
} else {
GradientPaint gradientShadowTmp = new GradientPaint(0, 0, new Color(240, 255, 210), 0, y + 15 + h / 2, new Color(204, 204, 204));
g2D.setPaint(gradientShadowTmp);
}
}
//selectColor = new Color(255, 255, 200);
//deSelectColor = new Color(240, 255, 210);
g2D.fill(shape);
if (runCount > 1) {
g2D.setColor(hazAlfa(getRunForTab(tabPane.getTabCount(), tabIndex) - 1));
g2D.fill(shape);
}
g2D.fill(shape);
}
#Override
protected void paintText(Graphics g, int tabPlacement, Font font, FontMetrics metrics, int tabIndex, String title, Rectangle textRect, boolean isSelected) {
super.paintText(g, tabPlacement, font, metrics, tabIndex, title, textRect, isSelected);
g.setFont(font);
View v = getTextViewForTab(tabIndex);
if (v != null) {
// html
v.paint(g, textRect);
} else {
// plain text
int mnemIndex = tabPane.getDisplayedMnemonicIndexAt(tabIndex);
if (tabPane.isEnabled() && tabPane.isEnabledAt(tabIndex)) {
g.setColor(tabPane.getForegroundAt(tabIndex));
BasicGraphicsUtils.drawStringUnderlineCharAt(g, title, mnemIndex, textRect.x, textRect.y + metrics.getAscent());
} else { // tab disabled
g.setColor(Color.BLACK);
BasicGraphicsUtils.drawStringUnderlineCharAt(g, title, mnemIndex, textRect.x, textRect.y + metrics.getAscent());
g.setColor(tabPane.getBackgroundAt(tabIndex).darker());
BasicGraphicsUtils.drawStringUnderlineCharAt(g, title, mnemIndex, textRect.x - 1, textRect.y + metrics.getAscent() - 1);
}
}
}
/*protected void paintText(Graphics g, int tabPlacement, Font font, FontMetrics metrics, int tabIndex, String title, Rectangle textRect, boolean isSelected) {
g.setFont(font);
View v = getTextViewForTab(tabIndex);
if (v != null) {
// html
v.paint(g, textRect);
} else {
// plain text
int mnemIndex = tabPane.getDisplayedMnemonicIndexAt(tabIndex);
if (tabPane.isEnabled() && tabPane.isEnabledAt(tabIndex)) {
Color fg = tabPane.getForegroundAt(tabIndex);
if (isSelected && (fg instanceof UIResource)) {
Color selectedFG = UIManager.getColor("TabbedPane.selectedForeground");
if (selectedFG != null) {
fg = selectedFG;
}
}
g.setColor(fg);
SwingUtilities2.drawStringUnderlineCharAt(tabPane, g, title, mnemIndex, textRect.x, textRect.y + metrics.getAscent());
} else { // tab disabled
//PAY ATTENTION TO HERE
g.setColor(tabPane.getBackgroundAt(tabIndex).brighter());
SwingUtilities2.drawStringUnderlineCharAt(tabPane, g, title, mnemIndex, textRect.x, textRect.y + metrics.getAscent());
g.setColor(tabPane.getBackgroundAt(tabIndex).darker());
SwingUtilities2.drawStringUnderlineCharAt(tabPane, g, title, mnemIndex,
textRect.x - 1, textRect.y + metrics.getAscent() - 1);
}
}
}*/
#Override
protected int calculateTabWidth(int tabPlacement, int tabIndex, FontMetrics metrics) {
return 20 + inclTab + super.calculateTabWidth(tabPlacement, tabIndex, metrics);
}
#Override
protected int calculateTabHeight(int tabPlacement, int tabIndex, int fontHeight) {
if (tabPlacement == LEFT || tabPlacement == RIGHT) {
return super.calculateTabHeight(tabPlacement, tabIndex, fontHeight);
} else {
return anchoFocoH + super.calculateTabHeight(tabPlacement, tabIndex, fontHeight);
}
}
#Override
protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected) {
}
#Override
protected void paintFocusIndicator(Graphics g, int tabPlacement, Rectangle[] rects, int tabIndex, Rectangle iconRect, Rectangle textRect, boolean isSelected) {
if (tabPane.hasFocus() && isSelected) {
g.setColor(UIManager.getColor("ScrollBar.thumbShadow"));
g.drawPolygon(shape);
}
}
protected Color hazAlfa(int fila) {
int alfa = 0;
if (fila >= 0) {
alfa = 50 + (fila > 7 ? 70 : 10 * fila);
}
return new Color(0, 0, 0, alfa);
}
}
The shape is under the aegis of the tabbed pane's UI delegate, which descends from TabbedPaneUI. The MetalTabbedPaneUI subclass is an example that may help you decide how badly you want to replace the delegate.
You can put html tags into the first parameter of addTab method as following :
MyJTabbedPane.addTab("<html><h1 style='padding:20px;'>TEST</h1></html>", new JPanel());