I'm trying to make this GUi.
I write my own layout because existing layout manager don't meet my requirements
It works but I attempt to optimize the creation of all buttons by using loops.
Test.class
public class Test {
public static void main(String[] args) {
JFrame f = new JFrame();
JPanel parent = new JPanel();
f.add(parent);
parent.setLayout(new BoxLayout(parent, BoxLayout.X_AXIS));
JPanel[] children = new JPanel[6];
for (int i = 1; i < children.length; i++) {
children[i] = new JPanel();
children[i].setLayout(new XYLayout());
children[i].setBorder(new LineBorder(Color.red));
parent.add(children[i]);
}
int x = 0, y = 375, w = 0, h = 50;
children[1].add(new JButton("8"), new XYConstraints(0, 25, 0, 50));
children[1].add(new JButton("7"), new XYConstraints(0, 75, 0, 50));
children[1].add(new JButton("6"), new XYConstraints(0, 125, 0, 50));
children[1].add(new JButton("5"), new XYConstraints(0, 175, 0, 50));
children[1].add(new JButton("4"), new XYConstraints(0, 225, 0, 50));
children[1].add(new JButton("3"), new XYConstraints(0, 275, 0, 50));
children[1].add(new JButton("2"), new XYConstraints(0, 325, 0, 50));
children[1].add(new JButton("1"), new XYConstraints(0, 375, 0, 50));
children[2].add(new JButton("7"), new XYConstraints(240, 25, 0, 100));
children[2].add(new JButton("6"), new XYConstraints(200, 75, 0, 100));
children[2].add(new JButton("5"), new XYConstraints(160, 125, 0, 100));
children[2].add(new JButton("4"), new XYConstraints(120, 175, 0, 100));
children[2].add(new JButton("3"), new XYConstraints(80, 225, 0, 100));
children[2].add(new JButton("2"), new XYConstraints(40, 275, 0, 100));
children[2].add(new JButton("1"), new XYConstraints(0, 325, 0, 100));
children[3].add(new JButton("6"), new XYConstraints(200, 25, 0, 150));
children[3].add(new JButton("5"), new XYConstraints(160, 75, 0, 150));
children[3].add(new JButton("4"), new XYConstraints(120, 125, 0, 150));
children[3].add(new JButton("3"), new XYConstraints(80, 175, 0, 150));
children[3].add(new JButton("2"), new XYConstraints(40, 225, 0, 150));
children[3].add(new JButton("1"), new XYConstraints(0, 275, 0, 150));
//children[4],//children[5]...
f.setSize(800, 600);
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
The custom layout in one file : XYLayout
public class XYLayout implements LayoutManager2, Serializable {
private int width;
private int height;
Hashtable<Component, Object> info;
static final XYConstraints defaultConstraints = new XYConstraints();
public XYLayout() {
info = new Hashtable<Component, Object>();
}
public XYLayout(int width, int height) {
info = new Hashtable<Component, Object>();
this.width = width;
this.height = height;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
/*
* (non-Javadoc)
*
* #see java.lang.Object#toString()
*/
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("XYLayout [width=").append(width).append(", height=").append(height).append("]");
return builder.toString();
}
public void addLayoutComponent(String s, Component component1) {
}
public void removeLayoutComponent(Component component) {
info.remove(component);
}
public Dimension preferredLayoutSize(Container target) {
return getLayoutSize(target, true);
}
public Dimension minimumLayoutSize(Container target) {
return getLayoutSize(target, false);
}
public void layoutContainer(Container target) {
Insets insets = target.getInsets();
int count = target.getComponentCount();
for (int i = 0; i < count; i++) {
Component component = target.getComponent(i);
if (component.isVisible()) {
Rectangle r = getComponentBounds(component, true);
component.setBounds(insets.left + r.x, insets.top + r.y, r.width, r.height);
}
}
}
public void addLayoutComponent(Component component, Object constraints) {
if (constraints instanceof XYConstraints)
info.put(component, constraints);
}
public Dimension maximumLayoutSize(Container target) {
return new Dimension(0x7fffffff, 0x7fffffff);
}
public float getLayoutAlignmentX(Container target) {
return 0.5F;
}
public float getLayoutAlignmentY(Container target) {
return 0.5F;
}
public void invalidateLayout(Container container) {
}
public Rectangle getComponentBounds(Component component, boolean doPreferred) {
XYConstraints constraints = (XYConstraints) info.get(component);
if (constraints == null)
constraints = defaultConstraints;
Rectangle r = new Rectangle(constraints.getX(), constraints.getY(), constraints.getW(), constraints.getH());
if (r.width <= 0 || r.height <= 0) {
Dimension d = doPreferred ? component.getPreferredSize() : component.getMinimumSize();
if (r.width <= 0)
r.width = d.width;
if (r.height <= 0)
r.height = d.height;
}
return r;
}
public Dimension getLayoutSize(Container target, boolean doPreferred) {
Dimension dim = new Dimension(0, 0);
if (width <= 0 || height <= 0) {
int count = target.getComponentCount();
for (int i = 0; i < count; i++) {
Component component = target.getComponent(i);
if (component.isVisible()) {
Rectangle r = getComponentBounds(component, doPreferred);
dim.width = Math.max(dim.width, r.x + r.width);
dim.height = Math.max(dim.height, r.y + r.height);
}
}
}
if (width > 0)
dim.width = width;
if (height > 0)
dim.height = height;
Insets insets = target.getInsets();
dim.width += insets.left + insets.right;
dim.height += insets.top + insets.bottom;
return dim;
}
}
class XYConstraints implements Cloneable, Serializable {
private int x;
private int y;
private int w;
private int h;
public XYConstraints() {
this(0, 0, 0, 0);
}
public XYConstraints(int x, int y, int w, int h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getW() {
return w;
}
public void setW(int w) {
this.w = w;
}
public int getH() {
return h;
}
public void setH(int h) {
this.h = h;
}
/*
* (non-Javadoc)
*
* #see java.lang.Object#hashCode()
*/
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + h;
result = prime * result + w;
result = prime * result + x;
result = prime * result + y;
return result;
// return x ^ y * 37 ^ w * 43 ^ h * 47;
}
public boolean equals(Object that) {
if (that instanceof XYConstraints) {
XYConstraints other = (XYConstraints) that;
return other.x == x && other.y == y && other.w == w && other.h == h;
} else {
return false;
}
}
public Object clone() {
return new XYConstraints(x, y, w, h);
}
/*
* (non-Javadoc)
*
* #see java.lang.Object#toString()
*/
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("XYConstraints [x=").append(x).append(", y=").append(y).append(", w=").append(w).append(", h=").append(h).append("]");
return builder.toString();
}
My first attempt was:
for (y = 375; y > 0; y = y - 50)
children[1].add(new JButton("1"), new XYConstraints(x, y, w, h));
for (y = 325, x = 0; y > 0 && x < 280; y = y - 50, x = x + 40)
children[2].add(new JButton("2"), new XYConstraints(x, y, w, 2 * h));
for (y = 275, x = 0; y > 0 && x < 240; y = y - 50, x = x + 40)
children[3].add(new JButton("3"), new XYConstraints(x, y, w, 3 * h));
but something's missing like a loop for "children[i]".I'm sure there is a better solution to improve the loop Any idea of improvement or suggestion ? Thanks
I write my own layout because existing layout manager don't meet my requirements
Right idea, but your implementation is incorrect. The fact that you need to provide the x/y values means you are not using a layout manager but just hardcoding some values.
Instead you need to provide information to the layout manager to define the parameters of the layout, maybe something like:
MyLayout layout = new MyLayout(xSize, ySize, xOffset, yOffset);
So for the first panel you would use:
MyLayout layout = new MyLayout(50, 50, 0, 50);
This code would say that each component is (50, 50). As you add components to the panel you change the x offset by 0 and the y offset = -50.
You know you have 8 buttons so you can use math to figure out the width/height of the panel. You can then use a loop inside the layout manager to position each component.
So now you add components to the panel like:
panel.add( new JButton("1") );
panel.add( new JButton("2") );
panel.add( new JButton("3") );
For the second panel you might use:
MyLayout layout = new MyLayout(50, 100, 50, 50);
So this time it means each button know has a size of (50, 100) and each button is placed (50, -50) to the previous button.
This is how layout managers should be created. You should not need complex loops to build the constraints of each component that you add to the panel. That is the job of the layout manager.
You could try:
for( int i=1; i<=3; i++ ) {
x = 0;
for( y=375-((i-1)*50; y>0; y-=50, x+=40 ) {
children[i].add(new JButton((String)i), new XYConstraints(x, y, w, i*h));
}
}
Related
Im trying to display the maximum number of smaller rectangles that will fit into a larger one. I can get the horizontal rectangles to show up, but the vertical rectangles will not show up. I need help on figuring out how to get the vertical rectangles to display in the JFrame.
Here is the class with the main:
import javax.swing.*;
public class MyPanel extends JComponent {
public static void main(String[] arguments) {
LargeRec large = new LargeRec();
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Rectangle");
frame.setResizable(false);
frame.setVisible(true);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setSize(500,400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(large);
}
}
This is the class for creating the rectangle's:
import javax.swing.*;
import java.awt.*;
public class LargeRec extends JComponent {
static int larX;
static int larY;
static int smaX;
static int smaY;
public static int getRandomIntRange(int min, int max) {
int x = (int) (Math.random() * ((max + 1 - min))) + min;
if (x > (max + 1))
x = max;
return x;
}
public void paint(Graphics g) {
larX = getRandomIntRange(100, 300);
larY = getRandomIntRange(100, 300);
while (larX == larY) {
larX = getRandomIntRange(100, 300);
larY = getRandomIntRange(100, 300);
}
while (larY > larX) {
larX = getRandomIntRange(100, 300);
larY = getRandomIntRange(100, 300);
}
smaX = getRandomIntRange(10, 50);
smaY = getRandomIntRange(10, 50);
while (smaX == smaY) {
smaX = getRandomIntRange(10, 50);
smaY = getRandomIntRange(10, 50);
}
while (smaY > smaX) {
smaX = getRandomIntRange(10, 50);
smaY = getRandomIntRange(10, 50);
}
g.drawRect(0, 0, larX, larY);
g.setColor(Color.black);
g.fillRect(0, 0, larX, larY);
int LX = larX;
int LY = larY;
int SX = smaX;
int SY = smaY;
for (int nx = 0; nx <= larX; nx = nx + smaX) {
while (LY >= SY) {
LY = LY - SY;
if(LX>=SX) {
g.setColor(Color.red);
g.drawRect(nx, LY, smaX, smaY);
}
}
LX = LX - SX;
LY = larY;
}
Graphics2D g2 = (Graphics2D) g;
for (int ny =LX; ny+smaY <=LX ; ny = ny + smaY) {
while (LY >= SX) {
g2.setColor(Color.blue);
g2.drawRect(ny, LY, smaY, smaX);
LY = LY - SX;
}
LY=larY;
}
}
}
It should output a black rectangle with smaller horizontal rectangles and vertical rectangles. It displays the horizontal (red) rectangles, but not the vertical(blue) rectangles.
Here is an example of a bad output:
I'm trying to build a JTabbedPane using BasicTabbedPaneUI. I found an example of it which doesn't works perfectly. But it doesn't have a close button so that i can close the current tab.
How can i add a close button in it?
Here is my code:
public class TabbedPane extends JPanel {
private static final long serialVersionUID = 1L;
public static final JButton backButton = new JButton();
public TabbedPane() {
setLayout(new BorderLayout());
JPanel jp = new JPanel();
jp.setLayout(new BorderLayout());
JTabbedPane tb = new JTabbedPane();
tb.setUI(new CustomTabbedPaneUI());
JPanel pane = new JPanel();
tb.add("Tab1", pane);
MyCloseButton button = new MyCloseButton();
jp.add(new JLayer<JTabbedPane>(tb));
jp.add(new JButton(new AbstractAction("add tab") {
#Override
public void actionPerformed(ActionEvent e) {
tb.addTab("test", new JPanel());
}
}), BorderLayout.SOUTH);
jp.add(tb, BorderLayout.CENTER);
add(jp, BorderLayout.CENTER);
}
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
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);
}
}
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)) {
MyCloseButton button = new MyCloseButton();
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);
}
}
}
#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);
}
}
Here is my Button class which i want to add in the code above
class MyCloseButton extends JButton{
public MyCloseButton() {
super("X");
setBorder(BorderFactory.createEmptyBorder());
setFocusPainted(false);
setBorderPainted(false);
setContentAreaFilled(false);
setRolloverEnabled(false);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(16, 16);
}
}
Hi I'm creating a program where the user needs to give certain inputs to gain points and there is a timer, but the timer is I created is making the cursor in the jtextfield to blink too fast for the program to take inputs at times. In my timer class I imported TimerTask and used timer.scheduleAtFixedRate() to count time. This isn't all my code but this is the main class.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
class Interface extends JPanel implements ActionListener {
private JTextField textField;
private int fontSize;
private Font font;
private GridBagConstraints c = new GridBagConstraints();
private int x, y;
private collection userInputData;
private boolean initialized = false;
private String[] answers;
private String[] questions;
private int points = 0;
private timer timer;
private boolean timerStarted = false;
Interface() {
super(new GridBagLayout());
x = 0;
y = 0;
userInputData = new collection();
setBackground(Color.BLACK);
timer = new timer(60);
questions = new String[] {"a", "b", "c", "d"};
answers = new String[] {"a","b","c","d","e","f","g" };
/*questions = new String[] {"云", "人", "口", "一"};
answers = new String[] {"去","十","二","大","运","中","丁" };*/
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
fontSize = getWidth() / 25;
Font font = new Font(g.getFont().getFontName(), Font.BOLD, fontSize);
g.setFont(font);
g.setColor(Color.WHITE);
if(initialized){
updateUserDataFrame();
updateFrame();
textField.requestFocus();
}
if (!timer.timeUp()) {
questions(g);
fontSize = getWidth() / 50;
Font n = new Font(g.getFont().getFontName(), Font.BOLD, fontSize);
g.setFont(n);
displayTimer(g);
points(g);
displayUserInput(g);
}
if (timer.timeUp()) {
displayScoreboard(g);
remove(textField);
}
}
private void displayTimer(Graphics g) {
if (!timerStarted) {
timer.start();
timerStarted = true;
}
//fontSize = getWidth() / 35;
timer.setColor(Color.RED);
timer.setPosition(getWidth() - (int) (getWidth() ), fontSize );
timer.displayTimer(g);
repaint();
}
private void displayScoreboard(Graphics g) {
int x = getWidth() / 50;
int y = getHeight() / 5;
g.drawString("Your Answers:", x, y);
/* String correctWrongNumber = "Correct: " + correctAnswers + " "
+ "Wrong: " + (question.length - correctAnswers);
x = getWidth() - g.getFontMetrics().stringWidth(correctWrongNumber) - getWidth() / 25;
g.drawString(correctWrongNumber, x, y);
x = getWidth() / 50;
y += getHeight() / 15 + fontSize;
for (int i = 0; i < studentAnswers.length; i++) {
g.drawString(i + 1 + ". " + studentAnswers[i], x, y);
x += getWidth() / 10.5;
}*/
}
private void points(Graphics g) {
int x = getWidth() / 4;
int y = getHeight() / 4;
g.setColor(Color.white);
g.drawString("Points: " + points, x, y);
}
private void questions( Graphics g) {
int x = getWidth() / 4;
int y = getHeight() / 8;
int borderY = getHeight() /60;
fontSize = getWidth() / 15;
Font font = new Font(g.getFont().getFontName(), Font.BOLD, fontSize);
g.setFont(font);
for(int i = 0; i < questions.length; i++) {
g.setColor(Color.red.brighter());
g.fillRect(x + 1, borderY, fontSize, fontSize);
g.setColor(Color.orange.brighter());
g.drawRect(x, borderY, fontSize, fontSize);
g.setColor(Color.white);
g.drawString(questions[i],x,y);
x += getWidth() / 6;
}
}
private void updateFrame() {
fontSize = getWidth() / 20;
font = new Font("SansSerif", Font.BOLD, fontSize);
textField.setFont(font);
c.insets = new Insets(0, 0, getHeight() / 2, 0);
remove(textField);
add(textField, c);
}
private void updateUserDataFrame(){
int x = getWidth()/60;
int y = getHeight()/3 + getHeight()/20;
int width = getWidth()/16;
int height = getWidth()/16;
int fontSize = getWidth()/20;
Font font = new Font("SansSerif", Font.BOLD, fontSize);
userInputData.reset();
while(userInputData.hasNext()){
structure temp = (structure)userInputData.next();
x += getWidth()/16;
temp.updateData(font, x, y, width, height);
}
}
private void displayUserInput(Graphics g) {
userInputData.paint(g);
}
void init(){
x = getWidth()/60;
y = getHeight()/3 + getHeight()/20;
fontSize = getWidth()/20;
font = new Font("SansSerif", Font.BOLD, fontSize);
textField = new JTextField(3);
textField.setFont(font);
textField.addActionListener(this);
//Add Components to this panel.
c.insets = new Insets(0, 0, getHeight()/2, 0);
c.gridx = 0;
c.gridy = 0;
add(textField, c);
updateUI();
initialized = true;
repaint();
}
#Override
public void actionPerformed(ActionEvent e) {
int buttonWidth = getWidth()/16;
int buttonHeight = getWidth()/16;
x += getWidth()/16;
String userInput = textField.getText();
for(int i = 0; i < answers.length; i++) {
if(answers[i].equals(textField.getText()))
points++;
}
userInputData.add(new structure(userInput, Color.WHITE, font,x,y,buttonWidth,buttonHeight));
textField.setText("");
repaint();
}
}
Edited: Timer class
import java.awt.*;
import java.util.Timer;
import java.util.TimerTask;
class timer {
private Timer timer = new Timer();
private int timeLimit;
private int x, y;
private Color color;
private TimerTask task = new TimerTask() {
public void run() {
timeLimit--;
if(timeLimit == 0){
timer.cancel();
}
}
};
timer() {
timeLimit = 120;
}
timer(int limit) {
timeLimit = limit;
}
void start() {
timer.scheduleAtFixedRate(task, 1000, 1000);
}
void displayTimer(Graphics g) {
int minute = timeLimit / 60;
int second = timeLimit % 60;
g.setColor(color);
if (minute < 10) {
if (second < 10)
g.drawString("0" + minute + ":0" + second, x, y);
else
g.drawString("0" + minute + ":" + second, x, y);
} else {
if (second < 10)
g.drawString(minute + ":0" + second, x, y);
else
g.drawString(minute + ":" + second, x, y);
}
}
void setColor(Color color) {
this.color = color;
}
void setPosition(int x, int y) {
this.x = x;
this.y = y;
}
int getTime() {
return timeLimit;
}
void setTime(int time) {
timeLimit = time;
}
boolean timeUp() {
return timeLimit == 0;
}
}
I don't understand where this timer is coming from ? You can use this code Timer timer = new Timer(1000,this); instead of timer timer = new timer(60);
Making 1000 enable to you use real timer.
I hope this make life your easier a bit.
I'm trying to write an algorithm to satisfy this challenge. I've double, triple, and quadruple checked my logic, but I think I'm missing something obvious. This program should group each color next to similar colors, but it produces something more akin to noise.
This is sort of what I expect (taken from a similar answer):
And this is what I'm actually getting:
public class AllColors extends JFrame {
private static final int WIDTH = 256;
private static final int HEIGHT = 128;
private static long TOTAL_ITERATIONS = (WIDTH * HEIGHT) * 185000;
private static int VALUES_PER_CHANNEL =32;
private static int CHANNEL_DELTA = 256/VALUES_PER_CHANNEL;
static BufferedImage image;
private static final int SCALE = 5;
static int[][] kernel = { { 0, 0, 1, 0, 0 },
{ 0, 2, 3, 2, 0 },
{ 1, 3, 0, 3, 1 },
{ 0, 2, 3, 2, 0 },
{ 0, 0, 1, 0, 0 } };
public static void main(String[] args) {
AllColors f = new AllColors();
f.setTitle("All Colors");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
image = new BufferedImage(WIDTH * SCALE, HEIGHT * SCALE, BufferedImage.TYPE_3BYTE_BGR);
init();
//gui stuff
JPanel p = new JPanel(){
#Override
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.scale(SCALE, SCALE);
g2.drawImage(image, 0, 0, null);
}
};
p.setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
f.add(p);
f.pack();
f.setVisible(true);
group(p);
}
//makes an image of all colors
private static void init() {
int x = 0;
int y = 0;
for(int r = 0; r < VALUES_PER_CHANNEL; r+= 1){
for(int g = 0; g < VALUES_PER_CHANNEL; g+= 1){
for(int b = 0; b < VALUES_PER_CHANNEL; b+= 1){
x++;
if(x % WIDTH == 0){
y++;
x = 0;
}
if(y >= HEIGHT)
return;
image.setRGB(x, y, new Color(r*CHANNEL_DELTA,g*CHANNEL_DELTA,b*CHANNEL_DELTA).getRGB());
}
}
}
}
//group together similar pixels
private static void group(JPanel panel){
Random rand = new Random();
for(long i = 0; i < TOTAL_ITERATIONS; i++){
Point first = new Point(rand.nextInt(WIDTH), rand.nextInt(HEIGHT));
Point second = new Point(rand.nextInt(WIDTH), rand.nextInt(HEIGHT));
trySwitch(first, second);
if(i % (WIDTH * HEIGHT) == 0){
System.out.println(i / (WIDTH * HEIGHT));
panel.repaint();
}
}
}
private static void swap(Point first, Point second){
int temp = image.getRGB(second.x, second.y);
image.setRGB(second.x, second.y, image.getRGB(first.x, first.y));
image.setRGB(first.x, first.y, temp);
}
//get how similar the neighbors are
private static int getNeighborDelta(int imageX, int imageY){
Color center = new Color(image.getRGB(imageX, imageY));
int sum = 0;
for (int x = 0; x < kernel[0].length; x++)
{
for (int y = 0; y < kernel.length; y++)
{
int weight = kernel[x][y];
if (weight <= 0)
{
continue;
}
int xOffset = x - (kernel[0].length / 2);
int yOffset = y - (kernel.length / 2);
try{
sum += getDistance(new Color(image.getRGB(imageX + xOffset, imageY + yOffset)), center) * weight;
}catch(ArrayIndexOutOfBoundsException e){
//if out of image
}
}
}
return sum;
}
//switches if the neighbors will be more similar
private static void trySwitch(Point first, Point second){
double firstDistance = getNeighborDelta(first.x, first.y);
swap(first, second);
double secondDistance = getNeighborDelta(first.x, first.y);
if(secondDistance > firstDistance)
swap(first, second);
}
//get similarity between colors
private static double getDistance(Color one, Color two){
int r = Math.abs(two.getRed() - one.getRed());
int g = Math.abs(two.getGreen() - one.getGreen());
int b = Math.abs(two.getBlue() - one.getBlue());
return r + g + b;
}
}
I want to change the height of each bar (for example 10 for red part and 20 for blue part). But when I increase the height value it will increase the chart from bottom whereas I want the change to top! Do you know what is wrong with it?
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ChartPanel extends JPanel {
private double[] values;
private String[] names;
private String title;
public ChartPanel(double[] v, String[] n, String t) {
names = n;
values = v;
title = t;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (values == null || values.length == 0)
return;
double minValue = 0;
double maxValue = 0;
for (int i = 0; i < values.length; i++) {
if (minValue > values[i])
minValue = values[i];
if (maxValue < values[i])
maxValue = values[i];
}
Dimension d = getSize();
int clientWidth = d.width;
int clientHeight = d.height;
int barWidth = clientWidth / values.length;
Font titleFont = new Font("SansSerif", Font.BOLD, 20);
FontMetrics titleFontMetrics = g.getFontMetrics(titleFont);
Font labelFont = new Font("SansSerif", Font.PLAIN, 10);
FontMetrics labelFontMetrics = g.getFontMetrics(labelFont);
int titleWidth = titleFontMetrics.stringWidth(title);
int y = titleFontMetrics.getAscent();
int x = (clientWidth - titleWidth) / 2;
g.setFont(titleFont);
g.drawString(title, x, y);
int top = titleFontMetrics.getHeight();
int bottom = labelFontMetrics.getHeight();
if (maxValue == minValue)
return;
double scale = (clientHeight - top - bottom) / (maxValue - minValue);
y = clientHeight - labelFontMetrics.getDescent();
g.setFont(labelFont);
for (int i = 0; i < values.length; i++) {
int valueX = i * barWidth + 1;
int valueY = top;
int height = (int) (values[i] * scale);
if (values[i] >= 0)
valueY += (int) ((maxValue - values[i]) * scale);
else {
valueY += (int) (maxValue * scale);
height = -height;
}
g.setColor(Color.red);
g.fillRect(valueX, valueY, barWidth - 80, height);
g.setColor(Color.black);
g.drawRect(valueX, valueY, barWidth - 80, height);
g.setColor(Color.blue);
g.fillRect(valueX, valueY + 20, barWidth - 80, height-20 );
g.setColor(Color.black);
g.drawRect(valueX, valueY + 20, barWidth - 80, height-20 );
int labelWidth = labelFontMetrics.stringWidth(names[i]);
x = i * barWidth + (barWidth - labelWidth) / 2;
g.drawString(names[i], x, y);
}
}
public static void main(String[] argv) {
JFrame f = new JFrame();
f.setSize(400, 300);
double[] values = new double[3];
String[] names = new String[3];
values[0] = 1;
names[0] = "Item 1";
values[1] = 2;
names[1] = "Item 2";
values[2] = 4;
names[2] = "Item 3";
f.getContentPane().add(new ChartPanel(values, names, "title"));
WindowListener wndCloser = new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
};
f.addWindowListener(wndCloser);
f.setVisible(true);
}
}
Because Java's graphics uses the top left corner as the origin, when you add to the height it will increase down instead of up. Try changing this:
g.setColor(Color.red);
g.fillRect(valueX, valueY, barWidth - 80, height);
g.setColor(Color.black);
g.drawRect(valueX, valueY, barWidth - 80, height);
To this:
g.setColor(Color.red);
g.fillRect(valueX, valueY - 20, barWidth - 80, height);
g.setColor(Color.black);
g.drawRect(valueX, valueY - 20, barWidth - 80, height);
I tried this and it added to the red portion of the bar at the top.
Here is a shot of the original code:
And with the change: