change how labels are drawn on elements

debugged concurrent modification exception on painting in Visual
This commit is contained in:
Macocian Adrian Radu
2020-06-30 15:53:19 +03:00
parent 33eb129120
commit 4428e45ddd
19 changed files with 127 additions and 425 deletions

24
resources/otherui.xml Normal file
View File

@@ -0,0 +1,24 @@
<?xml version="1.0"?>
<Window
Name="Window"
Visible="True"
Title="GUI DEMO"
Size="1024, 576">
<Button
BackgroundColor="#ff0000"
Label="Button 1"
Icon="circle"
Location="top_left"
Size="0.3f, 0.1f"/>
<ToggleButton
BackgroundColor="#00ff00"
Label="Button 2"
Icon="arrow_up_white"
Location="top_right"
Size="0.3f, 0.3f"/>
<Panel
BackgroundColor="#555555"
Size="0.5f, 0.5f"
Location="0f, 0.5f"
/>
</Window>

View File

@@ -25,28 +25,52 @@
Margins="10"
Name="Image"
Image="clover"/>
<RadioButtons
<RadioButtonList
Name="Radio Buttons"
Size="0.4f, 0.3f">
<RadioButton
Text="Up"
Label="Up"
Name="Up"
Size="300, 20"
Icon="circle"
/>
<RadioButton
Text="Middle"
Name="Middle"
Size="300, 20"
Icon="circle"
Label="Middle"
Name="Middle"
Size="300, 20"
Icon="circle"
/>
<RadioButton
Text="Down"
Name="Down"
Size="300, 20"
Icon="circle"
Label="Down"
Name="Down"
Size="300, 20"
Icon="circle"
/>
</RadioButtons>
</RadioButtonList>
<CheckBoxList
Name="Check Box"
Size="0.4f, 0.3f"
Location="0.5f, 0.0f">
<CheckBox
Label="Up"
Name="Up"
Size="300, 20"
Icon="circle"
/>
<CheckBox
Label="Middle"
Name="Middle"
Size="300, 20"
Icon="circle"
/>
<CheckBox
Label="Down"
Name="Down"
Size="300, 20"
Icon="circle"
/>
</CheckBoxList>
<InputTextBox
BackgroundColor="#999999"

View File

@@ -1,103 +1,22 @@
import guiTree.Components.Button;
import guiTree.Components.Panel;
import guiTree.Components.Picture;
import guiTree.Visual;
import guiTree.Window;
import guiTree.events.MouseAdapter;
import parser.XAMLParser;
import java.awt.event.MouseEvent;
import java.io.File;
public class Main {
public static void main(String[] args) {
Window window = null;
Visual.setEnableGPU(true);
try {
window = XAMLParser.parse("ui.xml");
window = XAMLParser.parse("otherui.xml");
} catch (Exception e) {
e.printStackTrace();
}
assert window != null;
Button topLeft = (Button) window.findByName("topLeft");
Button topCenter = (Button) window.findByName("topCenter");
Button topRight = (Button) window.findByName("topRight");
Button middleLeft = (Button) window.findByName("middleLeft");
Button middleCenter = (Button) window.findByName("middleCenter");
Button middleRight = (Button) window.findByName("middleRight");
Button bottomLeft = (Button) window.findByName("bottomLeft");
Button bottomCenter = (Button) window.findByName("bottomCenter");
Button bottomRight = (Button) window.findByName("bottomRight");
Picture picture = (Picture) window.findByName("Image");
Panel panel = (Panel) window.findByName("Panel");
topLeft.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent mouseEvent) {
picture.setLocation("top_left");
picture.update();
}
});
topRight.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent mouseEvent) {
picture.setLocation("top_right");
picture.update();
}
});
topCenter.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent mouseEvent) {
picture.setLocation("top_center");
picture.update();
}
});
middleLeft.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent mouseEvent) {
picture.setLocation("middle_left");
picture.update();
}
});
middleRight.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent mouseEvent) {
picture.setLocation("middle_right");
picture.update();
}
});
middleCenter.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent mouseEvent) {
picture.setLocation("middle_center");
picture.update();
}
});
bottomLeft.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent mouseEvent) {
picture.setLocation("bottom_left");
picture.update();
}
});
bottomRight.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent mouseEvent) {
picture.setLocation("bottom_right");
picture.update();
}
});
bottomCenter.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent mouseEvent) {
picture.setLocation("bottom_center");
picture.update();
}
});
}
}

View File

View File

@@ -1,37 +0,0 @@
package Sudoku;
import guiTree.Animations.ColorAnimation;
import guiTree.Components.ToggleButton;
import guiTree.events.KeyAdapter;
import java.awt.*;
import java.awt.event.KeyEvent;
public class SudokuButton extends ToggleButton {
private int number;
private boolean entered;
private boolean fixed;
private boolean toggle;
public SudokuButton(Boolean fixed) {
super();
this.fixed = fixed;
if(!fixed) {
addKeyListener(new SudokuKeyListener());
}
}
private class SudokuKeyListener extends KeyAdapter {
@Override
public void keyPressed(KeyEvent keyEvent) {
if(keyEvent.getKeyCode() >= 48 && keyEvent.getKeyCode() <= 57) {
setLabel(String.valueOf(keyEvent.getKeyCode() - 48));
}
else {
addAnimation(new ColorAnimation(SudokuButton.this, Color.RED, getBackgroundColor(), 100));
}
setPressed(false);
update();
}
}
}

View File

@@ -1,28 +0,0 @@
package Sudoku;
public class SudokuLayout {
public static String grid1 = "----3--67";
public static String grid2 = "-------35";
public static String grid3 = "---16---4";
public static String grid4 = "6-8-9---2";
public static String grid5 = "12--8--79";
public static String grid6 = "9---3-8-6";
public static String grid7 = "8---26---";
public static String grid8 = "69-------";
public static String grid9 = "35--9----";
public static String getGrid(int nr) {
switch(nr) {
case 1: return grid1;
case 2: return grid2;
case 3: return grid3;
case 4: return grid4;
case 5: return grid5;
case 6: return grid6;
case 7: return grid7;
case 8: return grid8;
case 9: return grid9;
}
return null;
}
}

View File

@@ -9,6 +9,7 @@ import guiTree.events.MouseAdapter;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
@@ -91,30 +92,41 @@ public class Button extends MenuItem {
//Draw Button
g.fillRoundRect(0, 0, getWidth(), getHeight(), round, round);
//Draw Label
if(getFont() != null) {
g.setFont(getFont());
}
g.setColor(this.getFontColor());
//Get Sizes
int textWidth = 0;
int textHeight = 0;
int iconWidth = 0;
int iconHeight = 0;
if(icon != null) {
iconWidth = icon.getWidth();
iconHeight = icon.getHeight();
}
if(!label.equals("")) {
textWidth = g.getFontMetrics().stringWidth(label);
textHeight = g.getFontMetrics().getHeight();
}
g.drawString(this.label, (this.getWidth() - textWidth)/2, (this.getHeight() + textHeight)/2);
//Draw Icon
if(icon != null) {
int iconWidth = icon.getWidth();
int iconHeight = icon.getHeight();
int iconX = (this.getWidth() - iconWidth - textWidth) / 2;
int iconY = (this.getHeight() - iconHeight - textHeight) / 2;
int iconX = (getWidth() - iconWidth - textWidth - 10) / 2;
int iconY = (getHeight() - iconHeight)/2;
Graphics2D g2 = (Graphics2D)imageBuffer.getGraphics();
g2.drawImage(icon, iconX, iconY, null);
g2.dispose();
}
//Draw Label
if(getFont() != null) {
g.setFont(getFont());
}
g.setColor(this.getFontColor());
if(!label.equals("")) {
int labelX = (getWidth() + iconWidth - textWidth) / 2;
int labelY = (getHeight() - textHeight) / 2 + g.getFontMetrics().getAscent();
g.drawString(this.label, labelX, labelY);
}
g.dispose();

View File

@@ -1,23 +1,13 @@
package guiTree.Components;
import guiTree.Animations.ColorAnimation;
import guiTree.Helper.Debugger;
import guiTree.Visual;
import guiTree.events.MouseAdapter;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class CheckBox extends Visual {
public class CheckBox extends ToggleButton {
public static int CHECKBOX_CLICKED = 3;
private BufferedImage icon;
private boolean hovered;
private boolean marked;
private String text;
public CheckBox() {
this(false, "");
@@ -32,88 +22,16 @@ public class CheckBox extends Visual {
}
public CheckBox(Boolean value, String text) {
super();
this.marked = value;
this.text = text;
setAccentColor(new Color(0.6f, 0.6f, 0.6f, 0.5f));
super(text);
setPressed(value);
this.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent mouseEvent) {
if(!marked) {
addAnimation(new ColorAnimation(CheckBox.this, getAccentColor(), getForegroundColor(), 100));
}
else {
addAnimation(new ColorAnimation(CheckBox.this, getForegroundColor(), getAccentColor(), 100));
}
marked = !marked;
notifyParent(CHECKBOX_CLICKED);
Debugger.log("Calling repaint from pressed: " + getName(), Debugger.Tag.PAINTING);
update();
}
@Override
public void mouseEntered(MouseEvent mouseEvent) {
if(!marked) {
addAnimation(new ColorAnimation(CheckBox.this, getBackgroundColor(), getAccentColor(), 100));
}
Debugger.log("Calling repaint from entered: " + getName(), Debugger.Tag.PAINTING);
update();
}
@Override
public void mouseExited(MouseEvent mouseEvent) {
if(!marked) {
addAnimation(new ColorAnimation(CheckBox.this, getAccentColor(), getBackgroundColor(), 100));
}
Debugger.log("Calling repaint from exited: " + getName(), Debugger.Tag.PAINTING);
update();
}
@Override
public void mouseMoved(MouseEvent mouseEvent) {
Debugger.log("Calling repaint from moved: " + getName(), Debugger.Tag.PAINTING);
}
});
}
public boolean isMarked() {
return marked;
}
public void setMarked(boolean marked) {
if(this.marked != marked) {
if (!this.marked) {
addAnimation(new ColorAnimation(this, getBackgroundColor(), getForegroundColor(), 100));
} else {
addAnimation(new ColorAnimation(this, getForegroundColor(), getBackgroundColor(), 100));
}
}
this.marked = marked;
update();
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
update();
}
public void setIcon(BufferedImage icon) {
this.icon = icon;
update();
}
public void setIcon(String url) {
try{
icon = ImageIO.read(new File("resources\\icons\\" + url + ".png"));
} catch (IOException e) {
e.printStackTrace();
}
update();
}
@Override
public void paint(Image imageBuffer) {
Graphics2D g = (Graphics2D)imageBuffer.getGraphics();
@@ -122,16 +40,16 @@ public class CheckBox extends Visual {
g.fillRect(1, 1, getHeight() - 1, getHeight() - 1);
if(marked) {
if(getPressed()) {
if(icon != null) {
int iconWidth = icon.getWidth();
int iconHeight = icon.getHeight();
if(getIcon() != null) {
int iconWidth = getIcon().getWidth();
int iconHeight = getIcon().getHeight();
int iconX = (this.getHeight() - iconWidth) / 2;
int iconY = (this.getHeight() - iconHeight) / 2;
int iconX = (getHeight() - iconWidth) / 2;
int iconY = (getHeight() - iconHeight) / 2;
Graphics2D g2 = (Graphics2D)imageBuffer.getGraphics();
g2.drawImage(icon, iconX, iconY, null);
g2.drawImage(getIcon(), iconX, iconY, null);
g2.dispose();
}
}
@@ -141,7 +59,7 @@ public class CheckBox extends Visual {
g.setFont(getFont());
}
int textHeight = g.getFontMetrics().getHeight();
g.drawString(text, getHeight() + 10, getHeight() / 2 + textHeight / 4);
g.drawString(getLabel(), getHeight() + 10, getHeight() / 2 + textHeight / 4);
g.dispose();
}

View File

@@ -145,7 +145,7 @@ public class CheckBoxList extends Visual {
public List<CheckBox> getActiveBoxes() {
List<CheckBox> markedBoxes = new ArrayList<>();
for(CheckBox cb: checkBoxList) {
if(cb.isMarked()) {
if(cb.getPressed()) {
markedBoxes.add(cb);
}
}

View File

@@ -11,7 +11,6 @@ import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
@@ -270,8 +269,7 @@ public class DropDown extends MenuItem implements Menu{
}
@Override
public void paint(Image imageBuffer)
{
public void paint(Image imageBuffer) {
//Get Graphics
Graphics2D g = (Graphics2D)imageBuffer.getGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

View File

@@ -99,7 +99,7 @@ public class GridPanel extends Visual {
update();
}
public void setRowPadding(int row, int col, int padding) {
public void setRowPadding(Integer row, Integer col, Integer padding) {
rowPadding.put(new Point2<>(col, row), padding);
for(int i = rowSizes.size(); i <= row + padding; i++) {
rowSizes.add(0);
@@ -107,7 +107,7 @@ public class GridPanel extends Visual {
updateSize();
}
public void setColumnPadding(int row, int col, int padding) {
public void setColumnPadding(Integer row, Integer col, Integer padding) {
columnPadding.put(new Point2<>(col, row), padding);
for(int i = columnSizes.size(); i <= col + padding; i++) {
columnSizes.add(0);
@@ -115,12 +115,12 @@ public class GridPanel extends Visual {
updateSize();
}
public void setRowSize(int row, int height) {
public void setRowSize(Integer row, Integer height) {
fixedRows.put(row, height);
updateSize();
}
public void setColumnSize(int column, int width) {
public void setColumnSize(Integer column, Integer width) {
fixedColumns.put(column, width);
updateSize();
}

View File

@@ -21,7 +21,6 @@ import java.util.List;
public class InputTextBox extends Visual {
private List<StringBuilder> lines;
private String title;
private Point2<Integer> caretPosition;
private Point2<Integer> startDragPosition;
private List<StringBuilder> selectedText;
@@ -30,20 +29,7 @@ public class InputTextBox extends Visual {
private int paragraphSpacing;
public InputTextBox() {
this(true, "");
}
public InputTextBox(Boolean visible) {
this(visible, "");
}
public InputTextBox(String title) {
this(true, title);
}
public InputTextBox(Boolean visible, String title) {
super();
this.title = title;
lines = new ArrayList<>();
selectionRectangles = new ArrayList<>();
lines.add(new StringBuilder());

View File

@@ -17,7 +17,7 @@ public class RadioButton extends CheckBox {
g.drawOval(1, 1, getHeight() - 2, getHeight() - 2);
if(isMarked()) {
if(getPressed()) {
if(getHeight() > 9) {
g.fillOval(5, 5, getHeight() - 9, getHeight() - 9);
}
@@ -28,7 +28,7 @@ public class RadioButton extends CheckBox {
g.setFont(getFont());
}
int textHeight = g.getFontMetrics().getHeight();
g.drawString(getText(), getHeight() + 10, getHeight() / 2 + textHeight / 4);
g.drawString(getLabel(), getHeight() + 10, getHeight() / 2 + textHeight / 4);
g.dispose();
}

View File

@@ -2,13 +2,13 @@ package guiTree.Components;
import guiTree.Visual;
public class RadioButtons extends CheckBoxList{
public class RadioButtonList extends CheckBoxList{
public void handleNotification(Visual v, int notify) {
if(notify == CheckBox.CHECKBOX_CLICKED) {
for(CheckBox cb: getActiveBoxes()) {
if(!cb.equals(v)) {
cb.setMarked(false);
cb.setPressed(false);
}
}
}
@@ -17,7 +17,7 @@ public class RadioButtons extends CheckBoxList{
public int getActiveButton() {
for(CheckBox rb: getActiveBoxes()) {
if(rb.isMarked()) {
if(rb.getPressed()) {
return getActiveBoxes().indexOf(rb);
}
}

View File

@@ -11,15 +11,10 @@ import java.util.List;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
public class ScrollPanel extends Visual {
private List<VisualLocation> children;
private float positionX;
private float positionY;
private float ratioX;
private float ratioY;
private Slider verticalScrollBar;
private Slider horizontalScrollBar;

View File

@@ -5,7 +5,6 @@ import guiTree.events.MouseAdapter;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
public class Slider extends Visual {
public static final int SLIDER_MOVED = 3;

View File

@@ -17,14 +17,12 @@ import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class Text extends Visual {
private List<StringBuilder> lines;
private String title;
private Point2<Integer> caretPosition;
private Point2<Integer> startDragPosition;
private List<StringBuilder> selectedText;
@@ -35,20 +33,7 @@ public class Text extends Visual {
private boolean selectable;
public Text() {
this(true, "");
}
public Text(Boolean visible) {
this(visible, "");
}
public Text(String title) {
this(true, title);
}
public Text(Boolean visible, String title) {
super();
this.title = title;
lines = new ArrayList<>();
selectionRectangles = new ArrayList<>();
lines.add(new StringBuilder());
@@ -95,14 +80,6 @@ public class Text extends Visual {
}
}
if(keyEvent.getKeyCode() == KeyEvent.VK_V) {
if(keyEvent.isControlDown()) {
pasteFromClipboard();
update();
return;
}
}
if(keyEvent.getKeyCode() == KeyEvent.VK_A) {
if(keyEvent.isControlDown()) {
selectAll();
@@ -192,25 +169,6 @@ public class Text extends Visual {
setSelection();
}
private void pasteFromClipboard() {
Transferable clipboardTransferable = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(this);
String clipboardText = null;
try {
clipboardText = (String) clipboardTransferable.getTransferData(DataFlavor.stringFlavor);
} catch (UnsupportedFlavorException | IOException e) {
e.printStackTrace();
}
if(clipboardText == null) {
return;
}
clipboardText = clipboardText.substring(0, clipboardText.length() -1 );
if(clipboardText.indexOf('\n') == -1) {
lines.get(caretPosition.y).insert(caretPosition.x, clipboardText);
caretPosition.x += clipboardText.length();
startDragPosition = caretPosition;
}
}
private Point2<Integer> getPositionOnScreen(int x, int y){
return textAligner.getPositionOnScreen(x, y);
}

View File

@@ -2,40 +2,30 @@ package guiTree.Components;
import guiTree.Animations.ColorAnimation;
import guiTree.Helper.Debugger;
import guiTree.Visual;
import guiTree.events.MouseAdapter;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
public class ToggleButton extends Visual {
private String label;
public class ToggleButton extends Button {
private Boolean pressed;
private BufferedImage icon;
public ToggleButton() {
this("", null);
}
public ToggleButton(String label) {
this(label, null);
public ToggleButton(String text) {
this(text, null);
}
public ToggleButton(BufferedImage icon) {
this(null, icon);
this("", icon);
}
public ToggleButton(String label, BufferedImage icon) {
super();
this.label = label;
this.icon = icon;
super(label, icon);
removeAllMouseListeners();
pressed = false;
this.addMouseListener(new MouseAdapter() {
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent mouseEvent) {
if(pressed) {
@@ -73,73 +63,14 @@ public class ToggleButton extends Visual {
});
}
@Override
public void paint(Image imageBuffer)
{
//Get Graphics
Graphics2D g = (Graphics2D)imageBuffer.getGraphics();
g.setColor(getPaintColor());
//Draw Button
g.fillRect(0, 0, getWidth() - 1, getHeight() - 1);
//Draw Label
if(getFont() != null) {
g.setFont(getFont());
}
g.setColor(this.getFontColor());
int textWidth = 0;
int textHeight = 0;
if(!label.equals("")) {
textWidth = g.getFontMetrics().stringWidth(label);
textHeight = g.getFontMetrics().getHeight();
}
g.drawString(this.label, (this.getWidth() - textWidth)/2, (this.getHeight() + textHeight)/2);
//Draw Icon
if(icon != null) {
int iconWidth = icon.getWidth();
int iconHeight = icon.getHeight();
int iconX = (this.getWidth() - iconWidth - textWidth) / 2;
int iconY = (this.getHeight() - iconHeight - textHeight) / 2;
Graphics2D g2 = (Graphics2D)imageBuffer.getGraphics();
g2.drawImage(icon, iconX, iconY, null);
g2.dispose();
}
g.dispose();
}
public void setLabel(String label) {
this.label = label;
}
public String getLabel() {
return this.label;
}
public void setIcon(BufferedImage icon) {
this.icon = icon;
}
public void setIcon(String url) {
try{
InputStream iconStream = getClass().getClassLoader().getResourceAsStream("icons/" + url + ".png");
assert iconStream != null;
icon = ImageIO.read(iconStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public BufferedImage getIcon() {
return icon;
}
public void setPressed(Boolean pressed) {
this.pressed = pressed;
if(!pressed) {
addAnimation(new ColorAnimation(ToggleButton.this, getPaintColor(), getBackgroundColor(), 100));
}
else {
addAnimation(new ColorAnimation(ToggleButton.this, getPaintColor(), getForegroundColor(), 100));
}
}
public Boolean getPressed() {

View File

@@ -94,6 +94,7 @@ public class Visual {
parent = null;
name = "";
backgroundColor = Color.WHITE;
paintColor = Color.WHITE;
foregroundColor = Color.BLUE;
fontColor = Color.BLACK;
accentColor = Color.BLUE;
@@ -142,13 +143,14 @@ public class Visual {
}
initializeImageBuffer();
locationPlacer.setElementSize(width, height);
setLocation();
for(Visual v: children) {
if(v.relativeHeight > 0.0 || v.relativeWidth > 0.0) {
v.setSize();
}
if(v.locationPlacer != null) {
v.locationPlacer.setParentSize(getWidth(), getHeight());
v.locationPlacer.setParentSize(width, height);
v.setLocation();
}
}
@@ -565,7 +567,8 @@ public class Visual {
clearImageBuffer();
paint(imageBuffer);
for (Visual v : children) {
for (int i = 0; i < children.size(); i++) {
Visual v = children.get(i);
if (v.dirty && v.active) {
v.revalidate();
}