Draw multiple rectangles on the swt canvas - java

First of all, this is an added question
Previous question :
Color change by area in swt?
I solved this once, but afterwards I tried to draw several boxes on this canvas, but an error came out and contact me
error
Exception in thread "main" org.eclipse.swt.SWTException: Graphic is disposed
at org.eclipse.swt.SWT.error(SWT.java:4869)
at org.eclipse.swt.SWT.error(SWT.java:4784)
at org.eclipse.swt.SWT.error(SWT.java:4755)
at org.eclipse.swt.graphics.GC.setBackground(GC.java:4122)
at View.MainWindow$2$1.paintControl(MainWindow.java:137)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:234)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89)
at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4195)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1037)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1061)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1046)
at org.eclipse.swt.widgets.Composite.WM_PAINT(Composite.java:1616)
at org.eclipse.swt.widgets.Control.windowProc(Control.java:4816)
at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:340)
at org.eclipse.swt.widgets.Display.windowProc(Display.java:4921)
at org.eclipse.swt.internal.win32.OS.DispatchMessage(Native Method)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3610)
at View.MainWindow.init(MainWindow.java:185)
at View.MainWindow.main(MainWindow.java:193)
my code
public class MainWindow implements Runnable {
/**
* Launch the application.
*
* #param args
*/
public void init() {
Display display = Display.getDefault();
Shell shell = new Shell();
shell.setSize(720, 500);
shell.setText("SWT Application");
shell.setLayout(null);
org.eclipse.swt.graphics.Color blue = display.getSystemColor(SWT.COLOR_BLUE);
org.eclipse.swt.graphics.Color green = display.getSystemColor(SWT.COLOR_GREEN);
org.eclipse.swt.graphics.Color darkBlue = display.getSystemColor(SWT.COLOR_DARK_BLUE);
org.eclipse.swt.graphics.Color red = display.getSystemColor(SWT.COLOR_RED);
org.eclipse.swt.graphics.Color gray = display.getSystemColor(SWT.COLOR_GRAY);
Canvas canvas = new Canvas(shell, SWT.NONE);
canvas.setBounds(41, 130, 640, 282);
Composite composite_1 = new Composite(canvas, SWT.NONE);
composite_1.setSize(1, 282);
Composite composite_2 = new Composite(canvas, SWT.NONE);
composite_2.setSize(640, 282);
composite_2.setBackground(blue);
Canvas canvas2 = new Canvas(composite_1, SWT.NONE);
canvas2.setBounds(0,0, 640, 282);
canvas2.setBackground(green);
Label lblNewLabel = new Label(composite_2, SWT.NONE);
lblNewLabel.setBounds(10, 69, 142, 156);
lblNewLabel.setImage(new Image(display, "C:\\image.png"));
Label degree0 = new Label(shell, SWT.NONE);
degree0.setBounds(0, 122, 35, 15);
degree0.setText(" 0 -");
Label degree360 = new Label(shell, SWT.NONE);
degree360.setBounds(0, 402, 35, 15);
degree360.setText("360 -");
Label startDistance = new Label(shell, SWT.NONE);
startDistance.setBounds(43, 423, 87, 15);
startDistance.setText("0 m");
Label previousDistance = new Label(shell, SWT.NONE);
previousDistance.setBounds(659, 423, 35, 15);
previousDistance.setText("30m");
/*ArrayList<Integer> compositeArray = new ArrayList<Integer>();
HashMap<Integer, Composite> myHashMap = new HashMap<Integer, Composite>();
for(int i=0; i<100; i++) { compositeArray.add(i); }
for(int i=0; i<=100; i++) {
myHashMap.put(i, Composite "$tempComposite"+compositeArray.get(i));
myHashMap.get(i).setBounds(0, 0, 0, 0);
}
myHashMap.forEach((k,v)->{
System.out.println("key: "+k+"value: "+v);
});
*/
//canvas.setBounds(41, 130, 640, 282);
canvas2.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
e.gc.setForeground(red);
e.gc.setBackground(red);
e.gc.drawRectangle(0, 0, 5, 10);
e.gc.dispose();
}
});
final Runnable run = new Runnable() {
private int counter = 0;
#Override
public void run() {
//Image Move
lblNewLabel.setLocation(lblNewLabel.getLocation().x + 1, lblNewLabel.getLocation().y);
//Composite Background GreenColor
composite_1.setSize(composite_1.getSize().x + 1, 282);
composite_1.setBackground(green);
// ramdom 함수
int random = (int) (Math.random() * 10);
int randomH = (int) (Math.random() * 30);
int randomW = (int) (Math.random() * 10) + 1;
// TODO : 그냥 사각형 을 생성 및 점 생성 해야될거 같음
// 0~2 중만 점찍기
switch (random) {
case 0: {
//canvas2.redraw();
canvas2.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
e.gc.setBackground(red);
e.gc.drawRectangle(composite_1.getSize().x, composite_1.getSize().y, 5, 15);
canvas2.dispose();
e.gc.dispose();
}
});
System.out.print(random);
break;
}
case 1: {
//canvas2.redraw();
canvas2.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
e.gc.setBackground(gray);
e.gc.drawRectangle(composite_1.getSize().x, composite_1.getSize().y, 5, 15);
canvas2.dispose();
e.gc.dispose();
}
});
System.out.print(random);
break;
}
case 2: {
//canvas2.redraw();
canvas2.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
e.gc.setBackground(darkBlue);
e.gc.drawRectangle(composite_1.getSize().x, composite_1.getSize().y, 5, 15);
canvas2.dispose();
e.gc.dispose();
}
});
System.out.print(random);
break;
}
}
display.timerExec(1000, this);
}
};
display.timerExec(1000, run);
shell.open();
shell.layout();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
public static void main(String[] args) {
MainWindow a = new MainWindow();
a.init();
}
public void redrawCanvas (Canvas canvas) {
GC gc = new GC(canvas);
gc.dispose();
}
#Override
public void run() {
// TODO Auto-generated method stub
Display.getDefault().timerExec(1000, this);
}
}
I also dispose of the GC, but I don't know why this error appears. Can you tell me where I was wrong?
Really swt is difficult so i need help

Remove all the
e.gc.dispose();
calls.
You should only call dispose on GC objects that you create with new GC(...), GC objects that SWT gives you must not be disposed.
You must also remove all the canvas2.dispose() calls. You must not dispose of a control until it will never be needed again.

Related

When centering dialog, first appears on topleft corner for some milliseconds

I'm generating a dialog with a lot of content. I want to pack the dialog to the childrens height, and I want to center it on screen, so I'm doing this after adding all the childrens:
shell.open();
shell.layout();
shell.pack(); //for wrap the dialog size to it's content width and height.
//the dialog must be centered after doing shell.pack();
Rectangle parentSize = getParent().getBounds();
Rectangle shellSize = shell.getBounds();
int x = parentSize.x + (parentSize.width - shellSize.width) / 2;
int y = (int) (parentSize.y + (parentSize.height - shellSize.height) / 3.5);
shell.setLocation(new Point(x, y));
The problem is that for some milliseconds the dialog is being visible with a lot of width and on the top left corner of the screen. I tried doing setVisible(false) and (true) to shell to do the trick but it doesn't works.
How can I avoid to see the dialog on the top left corner and with a lot of width for some milliseconds?
This is the full code:
public class SelectTwoMatrixNumbersDialog extends Dialog {
protected ArrayList<Integer> matrixNumbers1;
protected ArrayList<Integer> matrixNumbers2;
protected Shell shell;
private JointBet jointBet;
private boolean result;
NumbersMatrixWidget numbersMatrixWidget1;
NumbersMatrixWidget numbersMatrixWidget2;
/**
* Create the dialog.
* #param parent
* #param style
*/
public SelectTwoMatrixNumbersDialog(Shell parent, int style, JointBet jointBet) {
super(parent, style);
setText("Elegir Números");
this.jointBet = jointBet;
}
/**
* Open the dialog.
* #return the result
*/
public boolean open() {
createContents();
matrixNumbers1 = new ArrayList<Integer>();
matrixNumbers2 = new ArrayList<Integer>();
GridLayout gl_shell = new GridLayout(1, false);
gl_shell.marginWidth = 20;
gl_shell.marginHeight = 20;
shell.setLayout(gl_shell);
Composite contentComposite = new Composite(shell, SWT.NONE);
contentComposite.setLayout(new GridLayout(1, false));
contentComposite.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true, 1, 1));
Label lblNumbers = new Label(contentComposite, SWT.NONE);
lblNumbers.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1));
lblNumbers.setText("Números:");
Composite numbersContainerComposite = new Composite(contentComposite, SWT.NONE);
numbersContainerComposite.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1));
//variable values depending of type of game
boolean firstCellEmpty = jointBet.getGameType().getNumbersMatrixArray()[0].isFirstCellEmpty();
int matrix1Rows = jointBet.getGameType().getNumbersMatrixArray()[0].getRows();
int matrix1Columns = jointBet.getGameType().getNumbersMatrixArray()[0].getColumns();
int matrix1MinNumber = jointBet.getGameType().getNumbersMatrixArray()[0].getMinNumber();
int matrix1MaxNumber = jointBet.getGameType().getNumbersMatrixArray()[0].getMaxNumber();
GridLayout gl_numbersContainerComposite = new GridLayout(2, false);
gl_numbersContainerComposite.horizontalSpacing = 15;
numbersContainerComposite.setLayout(gl_numbersContainerComposite);
numbersMatrixWidget1 = new NumbersMatrixWidget(numbersContainerComposite, SWT.BORDER, false, jointBet.getGameType().getNumbersMatrixArray()[0].getNumbers(), matrix1Rows, matrix1Columns, matrix1MinNumber, matrix1MaxNumber, firstCellEmpty);
//variable values depending of type of game
firstCellEmpty = jointBet.getGameType().getNumbersMatrixArray()[1].isFirstCellEmpty();
int matrix2Rows = jointBet.getGameType().getNumbersMatrixArray()[1].getRows();
int matrix2Columns = jointBet.getGameType().getNumbersMatrixArray()[1].getColumns();
int matrix2MinNumber = jointBet.getGameType().getNumbersMatrixArray()[1].getMinNumber();
int matrix2MaxNumber = jointBet.getGameType().getNumbersMatrixArray()[1].getMaxNumber();
numbersMatrixWidget2 = new NumbersMatrixWidget(numbersContainerComposite, SWT.BORDER, false, jointBet.getGameType().getNumbersMatrixArray()[1].getNumbers(), matrix2Rows, matrix2Columns, matrix2MinNumber, matrix2MaxNumber, firstCellEmpty);
numbersMatrixWidget2.setLayoutData(new GridData(SWT.LEFT, SWT.BOTTOM, false, false, 1, 1));
Composite fillNumbersComposite = new Composite(shell, SWT.NONE);
fillNumbersComposite.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1));
fillNumbersComposite.setLayout(new GridLayout(1, false));
Composite compositeFillMatrix1 = new Composite(fillNumbersComposite, SWT.NONE);
compositeFillMatrix1.setLayout(new GridLayout(4, false));
Label lblFillMatrix1WithMostCommonNumbers1 = new Label(compositeFillMatrix1, SWT.NONE);
lblFillMatrix1WithMostCommonNumbers1.setText("Rellenar Matriz 1 con los");
Spinner matrix1NumbersSpinner = new Spinner(compositeFillMatrix1, SWT.BORDER);
matrix1NumbersSpinner.setMaximum(jointBet.getGameType().getNumbersMatrixArray()[0].getPossibleNumbersCount());
matrix1NumbersSpinner.setMinimum(1);
Label lblFillMatrix1WithMostCommonNumbers2 = new Label(compositeFillMatrix1, SWT.NONE);
lblFillMatrix1WithMostCommonNumbers2.setText("números mas repetidos:");
Button btnFillMatrix1 = new Button(compositeFillMatrix1, SWT.NONE);
btnFillMatrix1.setText("Rellenar");
btnFillMatrix1.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
String gameType = jointBet.getGameType().getType();
int matrix = 1;
int amount = Integer.parseInt(matrix1NumbersSpinner.getText());
numbersMatrixWidget1.setNumbers(StatisticsManager.getInstance().getMostUsedNumberKeys(gameType, matrix, amount));
}
});
Composite compositeFillMatrix2 = new Composite(fillNumbersComposite, SWT.NONE);
compositeFillMatrix2.setLayout(new GridLayout(4, false));
Label lblFillMatrix2WithMostCommonNumbers1 = new Label(compositeFillMatrix2, SWT.NONE);
lblFillMatrix2WithMostCommonNumbers1.setText("Rellenar Matriz 2 con los");
Spinner matrix2NumbersSpinner = new Spinner(compositeFillMatrix2, SWT.BORDER);
matrix2NumbersSpinner.setMaximum(jointBet.getGameType().getNumbersMatrixArray()[1].getPossibleNumbersCount());
matrix2NumbersSpinner.setMinimum(1);
Label lblFillMatrix2WithMostCommonNumbers2 = new Label(compositeFillMatrix2, SWT.NONE);
lblFillMatrix2WithMostCommonNumbers2.setText("números mas repetidos:");
Button btnFillMatrix2 = new Button(compositeFillMatrix2, SWT.NONE);
btnFillMatrix2.setText("Rellenar");
btnFillMatrix2.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
String gameType = jointBet.getGameType().getType();
int matrix = 2;
int amount = Integer.parseInt(matrix2NumbersSpinner.getText());
numbersMatrixWidget2.setNumbers(StatisticsManager.getInstance().getMostUsedNumberKeys(gameType, matrix, amount));
}
});
Composite buttonsComposite = new Composite(shell, SWT.NONE);
FillLayout fl_buttonsComposite = new FillLayout(SWT.HORIZONTAL);
fl_buttonsComposite.marginHeight = 10;
fl_buttonsComposite.spacing = 40;
buttonsComposite.setLayout(fl_buttonsComposite);
GridData gd_buttonsComposite = new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1);
gd_buttonsComposite.heightHint = 45;
buttonsComposite.setLayoutData(gd_buttonsComposite);
Button acceptButton = new Button(buttonsComposite, SWT.NONE);
acceptButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
//matrix 1
matrixNumbers1.clear();
for (Button b : numbersMatrixWidget1.getButtons()) {
if (b.getSelection()) {
matrixNumbers1.add(Integer.parseInt(b.getText()));
}
}
//matrix 2
matrixNumbers2.clear();
for (Button b : numbersMatrixWidget2.getButtons()) {
if (b.getSelection()) {
matrixNumbers2.add(Integer.parseInt(b.getText()));
}
}
if (matrixNumbers1.size()<jointBet.getGameType().getNumbersMatrixArray()[0].getNumbersPerBet() || matrixNumbers2.size()<jointBet.getGameType().getNumbersMatrixArray()[1].getNumbersPerBet()) {
ErrorDialog dialog = new ErrorDialog(shell, SWT.DIALOG_TRIM | SWT.PRIMARY_MODAL, "El mínimo de números es "+jointBet.getGameType().getNumbersMatrixArray()[0].getNumbersPerBet()+" + "+jointBet.getGameType().getNumbersMatrixArray()[1].getNumbersPerBet());
dialog.open();
}else {
Collections.sort(matrixNumbers1);
Collections.sort(matrixNumbers2);
jointBet.setNumbers(0, matrixNumbers1);
jointBet.setNumbers(1, matrixNumbers2);
DataManager.getInstance().saveData();
result = true;
shell.close();
}
}
});
acceptButton.setBounds(0, 0, 75, 25);
acceptButton.setText("Aceptar");
Button cancelButton = new Button(buttonsComposite, SWT.NONE);
cancelButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
result = false;
shell.close();
}
});
cancelButton.setBounds(0, 0, 75, 25);
cancelButton.setText("Cancelar");
shell.setDefaultButton(acceptButton);
shell.open();
shell.layout();
shell.pack(); //for wrap the dialog size to it's content width and height.
//the dialog must be centered after doing shell.pack();
Rectangle parentSize = getParent().getBounds();
Rectangle shellSize = shell.getBounds();
int x = parentSize.x + (parentSize.width - shellSize.width) / 2;
int y = (int) (parentSize.y + (parentSize.height - shellSize.height) / 3.5);
shell.setLocation(new Point(x, y));
Display display = getParent().getDisplay();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
return result;
}
/**
* Create contents of the dialog.
*/
private void createContents() {
shell = new Shell(getParent(), getStyle());
shell.setText(getText());
}
}
Just move the shell.open() to the end of the size calculations - after the shell.setLocation.

Previous instance of table appends to the newly invoked table. The page should show only one table

When I click the button called Enrolled Subjects, a table showing enrolled subjects is invoked. The data is loaded from a text file. But when I go to another page of the application and go back to the Enrolled Subjects or when I click the Enrolled Subjects Button again, a new table loads and adds to the previously loaded table. This makes the table grow longer every time I click Enrolled Subjects. I have added a removeAll() method which clears the content of the pane before loading the table again, but the previously loaded table, for some reason, does not go away.
Here's the code of the panel where the table is attached.
public class EnrolledSubjectsPanel extends JPanel
{
public EnrolledSubjectsPanel(String path)
{
setBackground(Color.LIGHT_GRAY);
setBounds(183, 280, 1129, 401);
setLayout(null);
LoadTable table = new LoadTable(path);
table.setBounds(0,60,1129,600);
add(table);
JLabel lblEnrolledSubjects = new JLabel("Enrolled Subjects");
lblEnrolledSubjects.setFont(new Font("Tahoma", Font.PLAIN, 35));
lblEnrolledSubjects.setBounds(446, 0, 292, 43);
add(lblEnrolledSubjects);
setVisible(true);
}
}
The class that creates the table
public class LoadTable extends JPanel
{
private static String path;
private static String header[] = {"Subject", "Schedule", "Room", "Proferssor", "Units"};
private static DefaultTableModel dtm = new DefaultTableModel(null, header);
boolean isLaunched;
public LoadTable(String path)
{
this.path = "subjects" + path;
setBackground(Color.LIGHT_GRAY);
setBounds(183, 280, 1129, 401);
setLayout(null);
JTable table = new JTable(dtm);
JScrollPane jsp = new JScrollPane(table);
jsp.setBounds(0, 0, 1129, 380);
add(jsp);
try
{
TextReaderBasic file = new TextReaderBasic(path);
String data[] = file.openFile();
int i = 0;
for(i = 0; i <= data.length; i++)
{
addRow(i);
}
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
setVisible(true);
}
public static void addRow(int x)
{
try
{
TextReaderBasic file = new TextReaderBasic(path);
String data[] = file.openFile();
int size = data.length;
int i = 0 + x;
int j = 6 + x;
int k = 12 + x;
int l = 18 + x;
int m = 24 + x;
dtm.addRow(new Object[]{data[i], data[j], data[k], data[l], data[m]});
}
catch(Exception e)
{
System.out.println("Action completed :)");
}
}
}
The main class where the panel is attached to
public class LaunchPage extends JFrame
{ public LaunchPage(String path)
{
getContentPane().setBackground(Color.white);
getContentPane().setLayout(null);
StudentBasicInformationPanel studentBasicInfo = new StudentBasicInformationPanel(path);
getContentPane().add(studentBasicInfo);
JLabel universityTitleL = new JLabel("Evil Genuises University");
universityTitleL.setFont(new Font("Edwardian Script ITC", Font.ITALIC, 42));
universityTitleL.setBounds(514, 11, 343, 65);
getContentPane().add(universityTitleL);
JPanel panelToAttach = new JPanel();
panelToAttach.setBounds(173, 280, 1129, 404);
getContentPane().add(panelToAttach);
setSize(1366, 768);
JButton enrollmentButton = new JButton("Enrollment");
enrollmentButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0)
{
panelToAttach.removeAll();
EnrollmentPanel ep = new EnrollmentPanel();
ep.setBackground(Color.LIGHT_GRAY);
ep.setBounds(0, 0, 1129, 401);
panelToAttach.add(ep);
repaint();
}
});
enrollmentButton.setBounds(10, 280, 157, 58);
getContentPane().add(enrollmentButton);
JButton viewEnrolledSubjectsButton = new JButton("Enrolled Subjects");
viewEnrolledSubjectsButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0)
{
panelToAttach.removeAll();
EnrolledSubjectsPanel es = new EnrolledSubjectsPanel(path);
es.setBackground(Color.LIGHT_GRAY);
es.setBounds(0, 0, 1129, 401);
panelToAttach.add(es);
repaint();
}
});
viewEnrolledSubjectsButton.setBounds(10, 349, 157, 58);
getContentPane().add(viewEnrolledSubjectsButton);
JButton viewGradesButton = new JButton("View Grades");
viewGradesButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0)
{
panelToAttach.removeAll();
GradesPanel gp = new GradesPanel();
gp.setBackground(Color.LIGHT_GRAY);
gp.setBounds(0, 0, 1129, 401);
panelToAttach.add(gp);
repaint();
}
});
viewGradesButton.setBounds(10, 418, 157, 58);
getContentPane().add(viewGradesButton);
JButton clearanceButton = new JButton("Clearance");
clearanceButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0)
{
panelToAttach.removeAll();
ClearancePanel cp = new ClearancePanel();
cp.setBackground(Color.LIGHT_GRAY);
cp.setBounds(0, 0, 1129, 401);
panelToAttach.add(cp);
repaint();
}
});
clearanceButton.setBounds(10, 487, 157, 58);
getContentPane().add(clearanceButton);
JButton viewAccountButton = new JButton("View Account");
viewAccountButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0)
{
panelToAttach.removeAll();
AccountPanel ap = new AccountPanel();
ap.setBackground(Color.LIGHT_GRAY);
ap.setBounds(0, 0, 1129, 401);
panelToAttach.add(ap);
repaint();
}
});
viewAccountButton.setBounds(10, 556, 157, 58);
getContentPane().add(viewAccountButton);
JButton closeButton = new JButton("Close");
closeButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
});
closeButton.setBounds(10, 626, 157, 58);
getContentPane().add(closeButton);
setVisible(true);
}
}
Thanks in advance!
Try using below code in your LoadTable class before you adding the rows to the table. It will clear the rows in the table model.
dtm.setRowCount(0);
So your new LoadTable class should look like this:
public class LoadTable extends JPanel
{
private static String path;
private static String header[] = {"Subject", "Schedule", "Room", "Proferssor", "Units"};
private static DefaultTableModel dtm = new DefaultTableModel(null, header);
dtm.setRowCount(0); //THIS WILL CLEAR THE ROWS IN YOUR STATIC TABLEMODEL
boolean isLaunched;
public LoadTable(String path)
{
this.path = "subjects" + path;
setBackground(Color.LIGHT_GRAY);
setBounds(183, 280, 1129, 401);
setLayout(null);
JTable table = new JTable(dtm);
JScrollPane jsp = new JScrollPane(table);
jsp.setBounds(0, 0, 1129, 380);
add(jsp);
try
{
TextReaderBasic file = new TextReaderBasic(path);
String data[] = file.openFile();
int i = 0;
for(i = 0; i <= data.length; i++)
{
addRow(i);
}
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
setVisible(true);
}
public static void addRow(int x)
{
try
{
TextReaderBasic file = new TextReaderBasic(path);
String data[] = file.openFile();
int size = data.length;
int i = 0 + x;
int j = 6 + x;
int k = 12 + x;
int l = 18 + x;
int m = 24 + x;
dtm.addRow(new Object[]{data[i], data[j], data[k], data[l], data[m]});
}
catch(Exception e)
{
System.out.println("Action completed :)");
}
}
}

Application not displaying GUI and won't quit Java

So I'm creating a game in Java and I ran into a little problem. Whenever I run the application the GUI does not show on the screen and the only way to close the application is to use the Windows Task Manager. In the application, you choose a username and click an enter button which creates a new window in which the game is played. But after you click the button, none of the GUI loads and you can't close the application.
Basically, when you click the button, a method is called that disposes the current window and starts the game window. The code for that method is below:
public void login(String name) {
String[] args={};
dispose();
SingleplayerGUI.main(args);
}
And here is the code of the SingleplayerGUI class:
public SingleplayerGUI(String userName, Singleplayer sp) {
this.userName = userName;
setResizable(false);
setTitle("Console Clash Singleplayer");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(880, 550);
setLocationRelativeTo(null);
System.setIn(inPipe);
try {
System.setOut(new PrintStream(new PipedOutputStream(outPipe), true));
inWriter = new PrintWriter(new PipedOutputStream(inPipe), true);
} catch (IOException e1) {
e1.printStackTrace();
}
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
GridBagLayout gbl_contentPane = new GridBagLayout();
gbl_contentPane.columnWidths = new int[] { 28, 815, 30, 7 }; // SUM = 880
gbl_contentPane.rowHeights = new int[] { 25, 485, 40 }; // SUM = 550
contentPane.setLayout(gbl_contentPane);
history = new JTextPane();
history.setEditable(false);
JScrollPane scroll = new JScrollPane(history);
caret = (DefaultCaret) history.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
GridBagConstraints scrollConstraints = new GridBagConstraints();
scrollConstraints.insets = new Insets(0, 0, 5, 5);
scrollConstraints.fill = GridBagConstraints.BOTH;
scrollConstraints.gridx = 0;
scrollConstraints.gridy = 0;
scrollConstraints.gridwidth = 2;
scrollConstraints.gridheight = 2;
scrollConstraints.weightx = 1;
scrollConstraints.weighty = 1;
scrollConstraints.insets = new Insets(0, 0, 5, -64);
contentPane.add(scroll, scrollConstraints);
txtMessage = new JTextField();
txtMessage.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
Color color = new Color(92, 219, 86);
String text = txtMessage.getText();
inWriter.println(text);
console(txtMessage.getText(), color);
command = txtMessage.getText();
}
}
});
GridBagConstraints gbc_txtMessage = new GridBagConstraints();
gbc_txtMessage.insets = new Insets(0, 0, 0, 25);
gbc_txtMessage.fill = GridBagConstraints.HORIZONTAL;
gbc_txtMessage.gridx = 0;
gbc_txtMessage.gridy = 2;
gbc_txtMessage.gridwidth = 2;
gbc_txtMessage.weightx = 1;
gbc_txtMessage.weighty = 0;
txtMessage.setColumns(5);
contentPane.add(txtMessage, gbc_txtMessage);
chat = new JTextPane();
chat.setEditable(false);
JScrollPane chatscroll = new JScrollPane(chat);
caret = (DefaultCaret) chat.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
GridBagConstraints chatscrollConstraints = new GridBagConstraints();
chatscrollConstraints.insets = new Insets(0, 0, 5, 5);
chatscrollConstraints.fill = GridBagConstraints.BOTH;
chatscrollConstraints.gridx = 0;
chatscrollConstraints.gridy = 0;
chatscrollConstraints.gridwidth = 2;
chatscrollConstraints.gridheight = 2;
chatscrollConstraints.weightx = 1;
chatscrollConstraints.weighty = 1;
chatscrollConstraints.insets = new Insets(150, 600, 5, -330);
contentPane.add(chatscroll, chatscrollConstraints);
chatMessage = new JTextField();
final String name = this.userName;
chatMessage.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
chatconsole(name + ": " + chatMessage.getText());
}
}
});
GridBagConstraints gbc_chatMessage = new GridBagConstraints();
gbc_txtMessage.insets = new Insets(000, 600, 000, -330);
gbc_txtMessage.fill = GridBagConstraints.HORIZONTAL;
gbc_txtMessage.gridx = 0;
gbc_txtMessage.gridy = 2;
gbc_txtMessage.gridwidth = 2;
gbc_txtMessage.weightx = 1;
gbc_txtMessage.weighty = 0;
txtMessage.setColumns(5);
contentPane.add(chatMessage, gbc_txtMessage);
JButton btnSend = new JButton("Send");
btnSend.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Color color = new Color(92, 219, 86);
String text = txtMessage.getText();
inWriter.println(text);
console(txtMessage.getText(), color);
command = txtMessage.getText();
}
});
GridBagConstraints gbc_btnSend = new GridBagConstraints();
gbc_btnSend.insets = new Insets(0, 0, 0, 275);
gbc_btnSend.gridx = 2;
gbc_btnSend.gridy = 2;
gbc_btnSend.weightx = 0;
gbc_btnSend.weighty = 0;
contentPane.add(btnSend, gbc_btnSend);
list = new JList();
GridBagConstraints gbc_list = new GridBagConstraints();
gbc_list.insets = new Insets(0, 600, 330, -330);
gbc_list.fill = GridBagConstraints.BOTH;
gbc_list.gridx = 0;
gbc_list.gridy = 0;
gbc_list.gridwidth = 2;
gbc_list.gridheight = 2;
JScrollPane p = new JScrollPane();
p.setViewportView(list);
contentPane.add(p, gbc_list);
list.setFont(new Font("Verdana", 0, 24));
System.out.println("HEY");
setVisible(true);
new SwingWorker<Void, String>() {
protected Void doInBackground() throws Exception {
Scanner s = new Scanner(outPipe);
while (s.hasNextLine()) {
String line = s.nextLine();
publish(line);
}
return null;
}
#Override protected void process(java.util.List<String> chunks) {
for (String line : chunks) {
try {
Document doc = history.getDocument();
doc.insertString(doc.getLength(), line + "\r\n", null);
} catch(BadLocationException exc) {
exc.printStackTrace();
}
}
}
}.execute();
Singleplayer spp = new Singleplayer();
Singleplayer.startOfGame();
setVisible(true);
}
public static void console(String message, Color color) {
txtMessage.setText("");
try {
StyledDocument doc = history.getStyledDocument();
Style style = history.addStyle("", null);
StyleConstants.setForeground(style, color);
doc.insertString(doc.getLength(), message + "\r\n", style);
} catch(BadLocationException exc) {
exc.printStackTrace();
}
}
public static void console(String message) {
txtMessage.setText("");
try {
Document doc = history.getDocument();
doc.insertString(doc.getLength(), message + "\r\n", null);
} catch(BadLocationException exc) {
exc.printStackTrace();
}
}
public void chatconsole(String message) {
chatMessage.setText("");
try {
Document doc = chat.getDocument();
doc.insertString(doc.getLength(), message + "\r\n", null);
} catch(BadLocationException exc) {
exc.printStackTrace();
}
}
public static void single() {
Singleplayer sp = new Singleplayer();
new SingleplayerGUI("", sp);
}
public static void main(String[] args) {
Singleplayer sp = new Singleplayer();
new SingleplayerGUI("", sp);
}
And the singleplayer class:
public static void startOfGame(){
System.out.println("HEY");
SingleplayerGUI.console("Welcome to Console Clash Pre Alpha Version 1!");
SingleplayerGUI.console("Created by Drift");
SingleplayerGUI.console("Published by Boring Games");
SingleplayerGUI.console("");
SingleplayerGUI.console("");
menuScreen();
}
static void menuScreen() {
Scanner scan = new Scanner(System.in);
System.out.println("To play the game, type 'start'. To quit, type 'quit'.");
String menu = scan.nextLine();
if (menu.equals("start")) {
start();
} else if (menu.equals("quit")) {
quit();
} else {
menuScreen();
}
}
private static void quit() {
SingleplayerGUI.console("You quit the game.");
}
private static void start() {
SingleplayerGUI.console("You started the game.");
}
So far I've figured out that the problem most likey occurs when adding the outPipe to the console. Would I be able to fix this or am I just not able to use outPipes with this application?
Thanks in advance for your help.
The setVisible() method is invoked twice.. Remove the second setVisible() call after the Singleplayer.startOfGame(); line in SingleplayerGUI constructor.

Using setOrigin method of ScrolledComposite

How can I make my ScrolledComposite scroll to show a specified control within it at the top?
This is a followup to a previous question of mine about how to make a ScrolledComposite programmatically scroll to a child control. The advice given there gave me some ideas on how to attempt it conceptually, such as using the setOrigin method, but I could not successfully get neither the given example nor my own to quite function. Here is what I've constructed so far:
I have made a shell that looks like this:
I have a bunch of labels from 1-500, and I have a bunch of specific buttons that I want to cause the ScrolledComposite to center on its respective label, like so:
Here is the code:
import java.util.HashMap;
public class ScrollableTest2 extends Shell {
private static final int NUM_OF_LABELS = 500;
private static final int[] SEEKABLES = new int[] {0, 9, 23, 99, 175, 176, 177, 178, 350, 495, 499};
Map<Integer, Control> controlMap = new HashMap<Integer, Control>();
private Composite cmpButtons;
private Label vr;
private ScrolledComposite scroller;
private Composite cmpScrollInner;
/**
* Launch the application.
* #param args
*/
public static void main(String args[]) {
try {
Display display = Display.getDefault();
ScrollableTest2 shell = new ScrollableTest2(display);
shell.layout();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Create the shell.
* #param display
*/
public ScrollableTest2(Display display) {
super(display, SWT.SHELL_TRIM);
createContents();
}
/**
* Create contents of the shell.
*/
protected void createContents() {
setSize(400, 400);
setText("SWT Application");
GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 3;
setLayout(gridLayout);
cmpButtons = new Composite(this, SWT.NONE);
cmpButtons.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1));
cmpButtons.setLayout(new GridLayout(1, false));
for (int seekable : SEEKABLES) {
Button button = new Button(cmpButtons, SWT.NONE);
button.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
button.setText("Go To " + String.valueOf(seekable+1));
final int index = seekable;
button.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
seekToLabel(index);
}
});
}
vr = new Label(this, SWT.SEPARATOR | SWT.VERTICAL);
vr.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, true, 1, 1));
scroller = new ScrolledComposite(this, SWT.BORDER | SWT.V_SCROLL);
scroller.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
scroller.setExpandHorizontal(true);
scroller.setExpandVertical(true);
cmpScrollInner = new Composite(scroller, SWT.NONE);
cmpScrollInner.setLayout(new GridLayout(1, false));
scroller.setContent(cmpScrollInner);
for (int i = 0; i < NUM_OF_LABELS; i++) {
Label label = new Label(cmpScrollInner, SWT.NONE);
label.setText("Label " + String.valueOf(i+1));
}
scroller.setMinSize(cmpScrollInner.computeSize(SWT.DEFAULT, SWT.DEFAULT));
scroller.setContent(cmpScrollInner);
scroller.addControlListener(new ControlAdapter() {
public void controlResized(ControlEvent e) {
Rectangle r = scroller.getClientArea();
scroller.setMinSize(cmpScrollInner.computeSize(r.width,
SWT.DEFAULT));
}
});
}
#Override
protected void checkSubclass() {
// Disable the check that prevents subclassing of SWT components
}
protected void seekToLabel(int index) {
Control showCntrl = controlMap.get(new Integer(index));
if(showCntrl != null){
scroller.setOrigin(showCntrl.getLocation());
}
}
}
The buttons do not seem to do anything at all, even though I believe that I am setting up the listeners correctly. I have to assume, then, that I am misusing the setOrigin command. What am I missing?
Neeeeevermind! Turns out, I simply forgot to add the control to the Map of controls. Once I did that, it works perfectly.
for (int i = 0; i < NUM_OF_LABELS; i++) {
Label label = new Label(cmpScrollInner, SWT.NONE);
label.setText("Label " + String.valueOf(i+1));
controlMap.put(new Integer(i), label);
}
It was a stupid mistake after all.

Java JTextPane + JScrollPane: de/activate automatic scrolling

I'm currently writing a simple chat in Java and currently I'm stuck on this problem:
I want my output JTextPane to behave like you would expect it to from a good chat, ie by default the text scrolls automatically when new text arrives (using outputfield.setCaretPosition(outputdocument.getLength())), but when the user scrolls up this should be disabled and of course re-enabled when the user scrolls to the bottom again.
I tried toying around with the ScrollBars and all, but I can't seem to find a way to detect whether the ScrollBar is at the bottom or not.
I create the scrollable output area simply by creating a JTextPane, a JScrollPane and put one into the other.
JTextPane outputpane = new JTextPane
...
JScrollPane outputscroll = new JScrollPane(outputpane);
outputscroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
Edit: Here's the code I use to create the components and display new messages:
// lots of imports
public class RoomFrame extends JFrame implements ListSelectionListener, ActionListener, Comparable, Runnable
{
public static final String DEFAULT_FONT = "Courier";
public static final int DEFAULT_FONT_SIZE = 12;
private JTextPane mOutputField;
private JScrollPane mOutputScroll;
private StyledDocument mOutputDocument;
public RoomFrame(...)
{
super(...);
createGUI();
setOutputStyles();
setVisible(true);
new Thread(this).start();
}
// ========================================================
private void createGUI()
{
Color borderhighlightouter = new Color(220, 220, 220);
Color borderhighlightinner = new Color(170, 170, 170);
Color bordershadowouter = new Color(120, 120, 120);
Color bordershadowinner = new Color(170, 170, 170);
setLayout(new GridBagLayout());
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setSize(500, 400);
// -----------------------------
// Output
mOutputField = new JTextPane();
mOutputField.setEditable(false);
mOutputField.setBackground(new Color(245, 245, 245));
mOutputDocument = mOutputField.getStyledDocument();
mOutputScroll = new JScrollPane(mOutputField);
mOutputScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
mOutputScroll.setPreferredSize(new Dimension(250, 250));
mOutputScroll.setMinimumSize(new Dimension(50, 50));
mOutputScroll.setOpaque(false);
mOutputScroll.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(0, 0, 1, 0), BorderFactory.createBevelBorder(BevelBorder.LOWERED, borderhighlightouter, borderhighlightinner, bordershadowouter, bordershadowinner)));
getContentPane().add(mOutputScroll);
}
private void setOutputStyles()
{
Style def = StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE);
Style regular = mOutputDocument.addStyle("regular", def);
StyleConstants.setFontFamily(def, DEFAULT_FONT);
StyleConstants.setFontSize(def, DEFAULT_FONT_SIZE);
StyleConstants.setFirstLineIndent(def, 100.0f);
Style nickname = mOutputDocument.addStyle("username", def);
StyleConstants.setBold(nickname, true);
StyleConstants.setForeground(nickname, new Color(50, 50, 220));
Style highlight = mOutputDocument.addStyle("highlight", def);
StyleConstants.setBold(highlight, true);
StyleConstants.setBackground(highlight, new Color(150, 0, 0));
Style join = mOutputDocument.addStyle("join", def);
StyleConstants.setBold(join, true);
StyleConstants.setForeground(join, new Color(20, 100, 20));
Style leave = mOutputDocument.addStyle("leave", def);
StyleConstants.setBold(leave, true);
StyleConstants.setForeground(leave, new Color(100, 100, 20));
Style topic = mOutputDocument.addStyle("topic", def);
StyleConstants.setBold(topic, true);
StyleConstants.setUnderline(topic, true);
Style error = mOutputDocument.addStyle("error", def);
StyleConstants.setBold(error, true);
StyleConstants.setForeground(error, new Color(255, 0, 0));
Style kick = mOutputDocument.addStyle("kick", def);
StyleConstants.setBold(kick, true);
StyleConstants.setForeground(kick, new Color(150, 0, 0));
}
private final boolean shouldScroll()
{
int min = mOutputScroll.getVerticalScrollBar().getValue() + mOutputScroll.getVerticalScrollBar().getVisibleAmount();
int max = mOutputScroll.getVerticalScrollBar().getMaximum();
return min == max;
}
// ========================================================
public void displayMessage(String message)
{
displayMessage(message, "");
}
public void displayMessage(String message, String style)
{
displayMessage(message, style, true);
}
public void displayMessage(String message, String style, boolean addnewline)
{
String newline = (addnewline ? "\n" : "");
style = (style.equals("") ? "regular" : style);
message = message.replace("\n", " ");
// check for highlight
try
{
mOutputDocument.insertString(mOutputDocument.getLength(),
String.format("%s%s", message, newline),
mOutputDocument.getStyle(style));
}
catch (Exception e) {}
// if (shouldScroll())
// mOutputField.setCaretPosition(mOutputDocument.getLength());
}
public void run()
{
while (true)
{
if (shouldScroll())
{
SwingUtilities.invokeLater(
new Runnable()
{
public void run()
{
mOutputScroll.getVerticalScrollBar().setValue(mOutputScroll.getVerticalScrollBar().getMaximum());
}
});
}
try { Thread.sleep(500); }
catch (InterruptedException e) { break; }
}
}
public void valueChanged(ListSelectionEvent event)
{
}
public void actionPerformed(ActionEvent event)
{
}
public final int compareTo(Object o) { return this.toString().compareTo(o.toString()); }
}
Edit: Thanks to fireshadow52's link to another similar question I finally got it to work exactly how I want it to:
private boolean isViewAtBottom()
{
JScrollBar sb = mOutputScroll.getVerticalScrollBar();
int min = sb.getValue() + sb.getVisibleAmount();
int max = sb.getMaximum();
System.out.println(min + " " + max);
return min == max;
}
private void scrollToBottom()
{
SwingUtilities.invokeLater(
new Runnable()
{
public void run()
{
mOutputScroll.getVerticalScrollBar().setValue(mOutputScroll.getVerticalScrollBar().getMaximum());
}
});
}
public void displayMessage(String message, String style, boolean prependnewline)
{
String newline = (prependnewline ? "\n" : "");
boolean scroll = isViewAtBottom() && prependnewline;
style = (style.equals("") ? "regular" : style);
message = message.replace("\n", " ");
try
{
mOutputDocument.insertString(mOutputDocument.getLength(),
String.format("%s%s", newline, message),
mOutputDocument.getStyle(style));
}
catch (Exception e) {}
if (scroll)
scrollToBottom();
}
Again, thanks for all your help!
If you're only wanting to scroll when you're at the bottom then this should help.
Use this method to check and see if the scrollbar is at the end (or bottom), and if so, scroll down automatically using setCaretPosition(Component.getDocument().getLength());:
public boolean shouldScroll() {
int minimumValue = scrollPane.getVerticalScrollBar().getValue() + scrollPane.getVerticalScrollBar().getVisibleAmount();
int maximumValue = scrollPane.getVerticalScrollBar().getMaximum();
return maximumValue == minimumValue;
}
I found similar results when using Google which led me to a method similar to this one which worked as requested.
Edit: Make sure that it is done within invokeLater() as it needs to be updated before scrolling is done.
A full example of what I use:
public class ScrollTest extends Thread {
private JFrame frame;
private JTextArea textArea;
private JScrollPane scrollPane;
public static void main(String[] arguments) {
new ScrollTest().run();
}
public ScrollTest() {
textArea = new JTextArea(20, 20);
scrollPane = new JScrollPane(textArea);
frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(scrollPane);
frame.pack();
frame.setVisible(true);
}
public void run() {
while (true) {
textArea.append("" + Math.random() + "\n");
if (shouldScroll()) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
scrollPane.getVerticalScrollBar().setValue(scrollPane.getVerticalScrollBar().getMaximum());
}
});
}
try {
Thread.sleep(500);
} catch (Exception exception) {
exception.printStackTrace();
}
}
}
public boolean shouldScroll() {
int minimumValue = scrollPane.getVerticalScrollBar().getValue() + scrollPane.getVerticalScrollBar().getVisibleAmount();
int maximumValue = scrollPane.getVerticalScrollBar().getMaximum();
return maximumValue == minimumValue;
}
}
JScrollBar has getValue() method. Just warp it in SwingUtilities.invokeLater() to be called after text appending.
You can use an AdjustmentListener to condtion scrolling, as shown in this example.

Categories