Depth system - previous 'top' item flashes upon change - java

I'm trying to set up a depth system of sorts in processing.
The goal is for it to function similar to a (Windows) window.
I have a class called 'Window' and that can take some arguments and it will successfully draw a window that can be dragged around.
The depth system works as it stands right now. I can't click on windows 'under' the current window and if I click on another window, the order of the windows is switched correctly.
The problem is that whenever I switch between windows, the previously selected window flashes (is not drawn) for a frame, and then appears again.
I cannot work out why this happens at all. Here's my code, let me know if you need any further info.
Windows.pde:
Window[] wins;
int win_count = 0;
boolean win_drag = false;
int win_selected = 2;
void setup()
{
size(800, 600);
wins = new Window[3];
wins[0] = new Window("Test", 20, 20, 300, 200);
wins[1] = new Window("Test 2", 20, 260, 350, 225);
wins[2] = new Window("Test 3", 400, 20, 250, 150);
}
void draw()
{
background(10);
for (int i = 0; i < wins.length; i ++)
{
wins[i].draw_window();
}
}
void bringToTop(Window winID)
{
Window[] new_wins;
new_wins = new Window[wins.length];
int win_pos = -1;
for (int i = 0; i < wins.length; i ++)
{
if (wins[i] == winID)
{
win_pos = i;
break;
}
}
arrayCopy(wins, 0, new_wins, 0, win_pos);
arrayCopy(wins, win_pos + 1, new_wins, win_pos, wins.length - win_pos - 1);
new_wins[wins.length - 1] = winID;
arrayCopy(new_wins, wins);
}
boolean isOnTop(Window winID)
{
int win_pos = -1;
for (int i = 0; i < wins.length; i ++)
{
if (wins[i] == winID)
{
win_pos = i;
break;
}
}
Window[] top_wins;
top_wins = new Window[wins.length];
int winTopCount = 0;
for (int i = 0; i < wins.length; i ++)
{
if (mouse_in_rect(wins[i].winX, wins[i].winY, wins[i].winW, wins[i].winH + 24))
{
top_wins[winTopCount] = wins[i];
winTopCount ++;
}
}
int last_real_win = -1;
for (int i = 0; i < top_wins.length; i ++)
{
if (top_wins[i] != null)
{
last_real_win = i;
}
}
return (wins[win_pos] == top_wins[last_real_win]);
}
WindowObj.pde:
class Window
{
String winT;
int winX;
int winY;
int winW;
int winH;
boolean dragging;
int winXOff;
int winYOff;
int winTH;
int my_id;
Window(String ttl, int WX, int WY, int WW, int WH)
{
winT = ttl;
winX = WX;
winY = WY;
winW = WW;
winH = WH;
dragging = false;
winXOff = 0;
winYOff = 0;
winTH = 24;
my_id = win_count ++;
}
void draw_window()
{
if (win_selected == my_id)
{
fill(60);
}
else
{
fill(40);
}
rect(winX, winY, winW, winTH);
fill(25);
rect(winX, winY + 24, winW, winH);
if (dragging == true)
{
winX = mouseX + winXOff;
winY = mouseY + winYOff;
if (winX < 0)
{
winX = 0;
}
if (winX > width - winW - 1)
{
winX = width - winW - 1;
}
if (winY < 0)
{
winY = 0;
}
if (winY > height - winH - winTH - 1)
{
winY = height - winH - winTH - 1;
}
}
Window win_pos = wins[0];
for (int i = 0; i < wins.length; i ++)
{
if (wins[i].my_id == my_id)
{
win_pos = wins[i];
}
}
if (mouse_in_rect(winX, winY, winW, 24) && mousePressed && mouseButton == LEFT && dragging == false && isOnTop(win_pos) && win_drag == false)
{
dragging = true;
winXOff = winX - mouseX;
winYOff = winY - mouseY;
win_drag = true;
win_selected = my_id;
bringToTop(win_pos);
}
if (mouse_in_rect(winX, winY + 24, winW, winH) && mousePressed && mouseButton == LEFT && dragging == false && isOnTop(win_pos) && win_drag == false)
{
win_selected = my_id;
bringToTop(win_pos);
}
if (dragging == true)
{
if (mouseButton != LEFT)
{
win_drag = false;
dragging = false;
winXOff = 0;
winYOff = 0;
}
}
}
}
mouseFunctions.pde:
boolean mouse_in_rect(int mX, int mY, int mW, int mH)
{
int but_x = mX;
int but_y = mY;
int but_w = mW;
int but_h = mH;
if (mouseX > but_x && mouseY > but_y && mouseX < but_x + but_w && mouseY < but_y + but_h)
{
return true;
}
else
{
return false;
}
}

The issue is caused, because you do the calculation of the window order and the drawing in a single loop.
If the position of a window has changed, the drawing of a window may be omitted, while the drawing of an other window is done twice. Note, the index of the windows in the array wins changed.
Split the drawing and the update of the windows to 2 separate methods:
class Window
{
// ...
void draw_window()
{
if (win_selected == my_id)
{
fill(60);
}
else
{
fill(40);
}
rect(winX, winY, winW, winTH);
fill(25);
rect(winX, winY + 24, winW, winH);
}
void update_window()
{
if (dragging == true)
{
// ...
}
// ...
}
First update the order of the windows and calculate its new position. After that draw all the windows in a separate loop:
void draw()
{
background(10);
for (int i = 0; i < wins.length; i ++) {
wins[i].update_window();
}
for (int i = 0; i < wins.length; i ++) {
wins[i].draw_window();
}
}

Related

Creating new levels

As a beginner in Java, I'm working on a project of Space Invaders. Looking to add more levels.
private void LevelInit() {
aliens = new ArrayList<>();
int currentLevel = 1;
if (currentLevel == 1) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j, Constants.ALIEN_INIT_Y + 18 * i);
aliens.add(alien);
//System.out.println(currentLevel);
}
}
}
else if (currentLevel == 2) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j, Constants.ALIEN_INIT_Y + 18 * i);
aliens.add(alien);
// System.out.println(currentLevel);
}
}
}
else if (currentLevel == 3) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 6; j++) {
var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j, Constants.ALIEN_INIT_Y + 18 * i);
aliens.add(alien);
//System.out.println(currentLevel);
}
}
}
player = new Player();
bullet = new Bullet();
}
This function is the logic behind the code that initializes the game and gets called by the constructor. The simple way of adding levels is adding more Aliens.
This is how it looks after being updated from yesterday, levels are being added but the arraylists are being stuck together. Like the 12 - 16 - 24 aliens are together printed, some spaceships take 1 hit some 2 and some 3 and when they are all destroyed system give message of You passed level 1 and 2 and 3 together which is confusing me why are they bound together like that and not being passed.
And I can't figure it out. Also,
private void update() {
if (deaths == 12) {
inGame = false;
timer.stop();
message = "Next Level!";
}
// player
player.act();
// shot
if (bullet.isVisible()) {
int shotX = bullet.getX();
int shotY = bullet.getY();
for (Alien alien : aliens) {
int alienX = alien.getX();
int alienY = alien.getY();
if (alien.isVisible() && bullet.isVisible()) {
if (shotX >= (alienX)
&& shotX <= (alienX + Constants.ALIEN_WIDTH)
&& shotY >= (alienY)
&& shotY <= (alienY + Constants.ALIEN_HEIGHT)) {
var ii = new ImageIcon(explImg);
alien.setImage(ii.getImage());
alien.setDying(true);
deaths++;
bullet.die();
}
}
}
int y = bullet.getY();
y -= 4;
if (y < 0) {
bullet.die();
} else {
bullet.setY(y);
}
}
// aliens
for (Alien alien : aliens) {
int x = alien.getX();
if (x >= Constants.BOARD_WIDTH - Constants.BORDER_RIGHT && direction != -1) {
direction = -1;
for(Alien a2 : aliens) {
a2.setY(a2.getY() + Constants.GO_DOWN);
}
}
if (x <= Constants.BORDER_LEFT && direction != 1) {
direction = 1;
for(Alien a : aliens) {
a.setY(a.getY() + Constants.GO_DOWN);
}
}
}
for(Alien alien : aliens) {
if (alien.isVisible()) {
int y = alien.getY();
if (y > Constants.GROUND - Constants.ALIEN_HEIGHT) {
inGame = false;
message = "Invasion!";
}
alien.act(direction);
}
}
// bombs
var generator = new Random();
for (Alien alien : aliens) {
int shot = generator.nextInt(15);
Alien.Bomb bomb = alien.getBomb();
if (shot == Constants.CHANCE && alien.isVisible() && bomb.isDestroyed()) {
bomb.setDestroyed(false);
bomb.setX(alien.getX());
bomb.setY(alien.getY());
}
int bombX = bomb.getX();
int bombY = bomb.getY();
int playerX = player.getX();
int playerY = player.getY();
if (player.isVisible() && !bomb.isDestroyed()) {
if (bombX >= (playerX)
&& bombX <= (playerX + Constants.PLAYER_WIDTH)
&& bombY >= (playerY)
&& bombY <= (playerY + Constants.PLAYER_HEIGHT)) {
var ii = new ImageIcon(explImg);
player.setImage(ii.getImage());
player.setDying(true);
bomb.setDestroyed(true);
}
}
if (!bomb.isDestroyed()) {
bomb.setY(bomb.getY() + 1);
if (bomb.getY() >= Constants.GROUND - Constants.BOMB_HEIGHT) {
bomb.setDestroyed(true);
}
}
}
}
This function is to update the game whenever anything happens. The code is made from a bunch of YouTube videos and GitHubs, so excuse the copying if you see any.
I need to create new levels by simply adding more aliens, tried using a for loop but that resulted in either the aliens move faster or the bullet doesn't destroy an alien, it just hits.
Board class:
public class Board extends JPanel {
private Dimension d;
private List<Alien> aliens;
private Player player;
private Bullet bullet;
private int level;
private int direction = -1;
private int deaths = 0;
private boolean inGame = true;
private String explImg = "src/images/explosion.png";
private String message = "Game Over";
private Timer timer;
public Board() {
initBoard();
gameInit();
LevelInit();
}
private void initBoard() {
addKeyListener(new TAdapter());
setFocusable(true);
d = new Dimension(Constants.BOARD_WIDTH, Constants.BOARD_HEIGHT);
setBackground(Color.black);
timer = new Timer(Constants.DELAY, new GameCycle());
timer.start();
gameInit();
}
private void gameInit() {
aliens = new ArrayList<>();
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j,
Constants.ALIEN_INIT_Y + 18 * i);
aliens.add(alien);
}
}
player = new Player();
bullet = new Bullet();
}
private void LevelInit() {
inGame = true;
timer.start();
int level = 1;
if (aliens.isEmpty()) {
level++;
int AlienCount;if(level == 2) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 6; j++) {
var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j, Constants.ALIEN_INIT_Y + 18 * i);
aliens.add(alien);
}
}
} else if (level == 3) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 6; j++) {
var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j, Constants.ALIEN_INIT_Y + 18 * i);
aliens.add(alien);
}
}
}
}
player = new Player();
bullet = new Bullet();
}
private void drawAliens(Graphics g) {
for (Alien alien : aliens) {
if (alien.isVisible()) {
g.drawImage(alien.getImage(), alien.getX(), alien.getY(), this);
}
if (alien.isDying()) {
alien.die();
}
}
}
private void drawPlayer(Graphics g) {
if (player.isVisible()) {
g.drawImage(player.getImage(), player.getX(), player.getY(), this);
}
if (player.isDying()) {
player.die();
inGame = false;
}
}
private void drawShot(Graphics g) {
if (bullet.isVisible()) {
g.drawImage(bullet.getImage(), bullet.getX(), bullet.getY(), this);
}
}
private void drawBombing(Graphics g) {
for (Alien a : aliens) {
Alien.Bomb b = a.getBomb();
if (!b.isDestroyed()) {
g.drawImage(b.getImage(), b.getX(), b.getY(), this);
}
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
private void doDrawing(Graphics g) {
g.setColor(Color.black);
g.fillRect(0, 0, d.width, d.height);
g.setColor(Color.green);
if (inGame) {
g.drawLine(0, Constants.GROUND,
Constants.BOARD_WIDTH, Constants.GROUND);
drawAliens(g);
drawPlayer(g);
drawShot(g);
drawBombing(g);
} else {
if (timer.isRunning()) {
timer.stop();
}
gameOver(g);
}
Toolkit.getDefaultToolkit().sync();
}
private void gameOver(Graphics g) {
g.setColor(Color.black);
g.fillRect(0, 0, Constants.BOARD_WIDTH, Constants.BOARD_HEIGHT);
g.setColor(new Color(0, 32, 48));
g.fillRect(50, Constants.BOARD_WIDTH / 2 - 30, Constants.BOARD_WIDTH - 100, 50);
g.setColor(Color.white);
g.drawRect(50, Constants.BOARD_WIDTH / 2 - 30, Constants.BOARD_WIDTH - 100, 50);
var small = new Font("Helvetica", Font.BOLD, 14);
var fontMetrics = this.getFontMetrics(small);
g.setColor(Color.white);
g.setFont(small);
g.drawString(message, (Constants.BOARD_WIDTH - fontMetrics.stringWidth(message)) / 2,
Constants.BOARD_WIDTH / 2);
}
private void update() {
if (deaths == aliens.size()) {
inGame = false;
timer.stop();
message = "Next Level!";
}
// player
player.act();
// shot
if (bullet.isVisible()) {
int shotX = bullet.getX();
int shotY = bullet.getY();
for (Alien alien : aliens) {
int alienX = alien.getX();
int alienY = alien.getY();
if (alien.isVisible() && bullet.isVisible()) {
if (shotX >= (alienX)
&& shotX <= (alienX + Constants.ALIEN_WIDTH)
&& shotY >= (alienY)
&& shotY <= (alienY + Constants.ALIEN_HEIGHT)) {
var ii = new ImageIcon(explImg);
alien.setImage(ii.getImage());
alien.setDying(true);
deaths++;
bullet.die();
}
}
}
int y = bullet.getY();
y -= 4;
if (y < 0) {
bullet.die();
} else {
bullet.setY(y);
}
}
// aliens
for (Alien alien : aliens) {
int x = alien.getX();
if (x >= Constants.BOARD_WIDTH - Constants.BORDER_RIGHT && direction != -1) {
direction = -1;
Iterator<Alien> i1 = aliens.iterator();
while (i1.hasNext()) {
Alien a2 = i1.next();
a2.setY(a2.getY() + Constants.GO_DOWN);
}
}
if (x <= Constants.BORDER_LEFT && direction != 1) {
direction = 1;
Iterator<Alien> i2 = aliens.iterator();
while (i2.hasNext()) {
Alien a = i2.next();
a.setY(a.getY() + Constants.GO_DOWN);
}
}
}
Iterator<Alien> it = aliens.iterator();
while (it.hasNext()) {
Alien alien = it.next();
if (alien.isVisible()) {
int y = alien.getY();
if (y > Constants.GROUND - Constants.ALIEN_HEIGHT) {
inGame = false;
message = "Invasion!";
}
alien.act(direction);
}
}
// bombs
var generator = new Random();
for (Alien alien : aliens) {
int shot = generator.nextInt(15);
Alien.Bomb bomb = alien.getBomb();
if (shot == Constants.CHANCE && alien.isVisible() && bomb.isDestroyed()) {
bomb.setDestroyed(false);
bomb.setX(alien.getX());
bomb.setY(alien.getY());
}
int bombX = bomb.getX();
int bombY = bomb.getY();
int playerX = player.getX();
int playerY = player.getY();
if (player.isVisible() && !bomb.isDestroyed()) {
if (bombX >= (playerX)
&& bombX <= (playerX + Constants.PLAYER_WIDTH)
&& bombY >= (playerY)
&& bombY <= (playerY + Constants.PLAYER_HEIGHT)) {
var ii = new ImageIcon(explImg);
player.setImage(ii.getImage());
player.setDying(true);
bomb.setDestroyed(true);
}
}
if (!bomb.isDestroyed()) {
bomb.setY(bomb.getY() + 1);
if (bomb.getY() >= Constants.GROUND - Constants.BOMB_HEIGHT) {
bomb.setDestroyed(true);
}
}
}
}
private void doGameCycle() {
update();
repaint();
}
private class GameCycle implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
doGameCycle();
}
}
private class TAdapter extends KeyAdapter {
#Override
public void keyReleased(KeyEvent e) {
player.keyReleased(e);
}
#Override
public void keyPressed(KeyEvent e) {
player.keyPressed(e);
int x = player.getX();
int y = player.getY();
int key = e.getKeyCode();
if (key == KeyEvent.VK_SPACE) {
if (inGame) {
if (!bullet.isVisible()) {
bullet = new Bullet(x, y);
}
}
}
}
}
}
As #JoachimSauer mentioned, your code needs refactoring. Here is one possible solution to your problem.
Additions
You will need two extra variables and one extra method.
Variables
1: int currentLevel - keeps track of the current level
2: boolean isLevelOver - keeps track if the current level is still active or not
Method
private void levelInit(int currentlevel)
{
aliens = new ArrayList<>();
int alienCount = //calculate alien count depending upon the current level
//Add aliens to aliens ArrayList
player = new Player();
bullet = new Bullet();
}
You have to provide implementation of how alienCount will be calculated depending upon currentLevel. The nested loop you used earlier to add aliens to aliens will also change. You have to make the loop dependent upon currentLevel.
Changes
Few of your methods will require some change.
public Board()
{
initBoard();
}
private void initBoard()
{
addKeyListener(new TAdapter());
setFocusable(true);
d = new Dimension(Constants.BOARD_WIDTH, Constants.BOARD_HEIGHT);
setBackground(Color.black);
levelInit(currentLevel);
timer = new Timer(Constants.DELAY, new GameCycle());
timer.start();
}
private void update()
{
if (deaths == aliens.size())
{
isLevelOver = true;
currentLevel++;
message = "Next Level!";
return;
}
...
}
private void doGameCycle()
{
if (isLevelOver)
{
levelInit(currentLevel);
isLevelOver = false;
}
update();
repaint();
}
Notes
This is one of the possible ways to achieve what you want. There
might be other ways, probably better, but this is what I came up
with.
I tried to find as many additions and updation required in your code. However, I do not know its structure, you do. So there might be more additions or changes required.
I noticed you are were calling gameInit() in initBoard() and then again in Board() constructor. I think that might be unnecessary, please look into it.
You made one call to timer.stop() after setting isGame = false. This again might be unnecessary since you are already doing so inside doDrawing(...). Please also check that.
You should probably set a limit to either the levelCount() or max alien that can be on the screen since if you just keep on adding more aliens in each new level, they might fill up the entire screen.
I have provided many hints which should help you in your problem. If you still face any more problems or someone finds anything wrong with the answer, please comment.

Intersection of Rectangles for Java (Freeze Tag)

**Edited still not getting the right response **
I am not quite understanding how to figure out the intersection aspect of my project. So far I have determined the top, bottom, left and right but I am not sure where to go from there.
The main driver should call to check if my moving rectangles are intersecting and if the rectangle is froze the moving one intersecting with it should unfreeze it and change its color. I understand how to unfreeze it and change the color but for whatever the reason it isn't returning the value as true when they are intersecting and I know this code is wrong. Any helpful tips are appreciated.
*CLASS CODE*
import edu.princeton.cs.introcs.StdDraw;
import java.util.Random;
import java.awt.Color;
public class MovingRectangle {
Random rnd = new Random();
private int xCoord;
private int yCoord;
private int width;
private int height;
private int xVelocity;
private int yVelocity;
private Color color;
private boolean frozen;
private int canvas;
public MovingRectangle(int x, int y, int w, int h, int xv, int yv, int canvasSize) {
canvas = canvasSize;
xCoord = x;
yCoord = y;
width = w;
height = h;
xVelocity = xv;
yVelocity = yv;
frozen = false;
int c = rnd.nextInt(5);
if (c == 0) {
color = StdDraw.MAGENTA;
}
if (c == 1) {
color = StdDraw.BLUE;
}
if (c == 2) {
color = StdDraw.CYAN;
}
if (c == 3) {
color = StdDraw.ORANGE;
}
if (c == 4) {
color = StdDraw.GREEN;
}
}
public void draw() {
StdDraw.setPenColor(color);
StdDraw.filledRectangle(xCoord, yCoord, width, height);
}
public void move() {
if (frozen == false) {
xCoord = xCoord + xVelocity;
yCoord = yCoord + yVelocity;
}
else {
xCoord +=0;
yCoord +=0;
}
if (xCoord >= canvas || xCoord < 0) {
xVelocity *= -1;
this.setRandomColor();
}
if (yCoord >= canvas || yCoord < 0) {
yVelocity *= -1;
this.setRandomColor();
}
}
public void setColor(Color c) {
StdDraw.setPenColor(color);
}
public void setRandomColor() {
int c = rnd.nextInt(5);
if (c == 0) {
color = StdDraw.MAGENTA;
}
if (c == 1) {
color = StdDraw.BLUE;
}
if (c == 2) {
color = StdDraw.CYAN;
}
if (c == 3) {
color = StdDraw.ORANGE;
}
if (c == 4) {
color = StdDraw.GREEN;
}
}
public boolean containsPoint(double x, double y) {
int bottom = yCoord - height / 2;
int top = yCoord + height / 2;
int left = xCoord - width / 2;
int right = xCoord + width / 2;
if (x > left && x < right && y > bottom && y < top) {
color = StdDraw.RED;
return true;
} else {
return false;
}
}
public boolean isFrozen() {
if (frozen) {
return true;
} else {
return false;
}
}
public void setFrozen(boolean val) {
frozen = val;
}
public boolean isIntersecting(MovingRectangle r) {
int top = xCoord + height/2;
int bottom = xCoord - height/2;
int right = yCoord + width/2;
int left = yCoord - width/2;
int rTop = r.xCoord + r.height/2;
int rBottom = r.xCoord - r.height/2;
int rRight = r.yCoord + r.width/2;
int rLeft = r.yCoord - r.width/2;
if(right <= rRight && right >= rLeft || bottom <= rBottom && bottom
>= rTop){
return true;
} else {
return false;
}
}
}
Here is my main driver as well, because I might be doing something wrong here too.
import edu.princeton.cs.introcs.StdDraw;
import java.util.Random;
public class FreezeTagDriver {
public static final int CANVAS_SIZE = 800;
public static void main(String[] args) {
StdDraw.setCanvasSize(CANVAS_SIZE, CANVAS_SIZE);
StdDraw.setXscale(0, CANVAS_SIZE);
StdDraw.setYscale(0, CANVAS_SIZE);
Random rnd = new Random();
MovingRectangle[] recs;
recs = new MovingRectangle[5];
boolean frozen = false;
for (int i = 0; i < recs.length; i++) {
int xv = rnd.nextInt(4);
int yv = rnd.nextInt(4);
int x = rnd.nextInt(400);
int y = rnd.nextInt(400);
int h = rnd.nextInt(100) + 10;
int w = rnd.nextInt(100) + 10;
recs[i] = new MovingRectangle(x, y, w, h, xv, yv, CANVAS_SIZE);
}
while (true) {
StdDraw.clear();
for (int i = 0; i < recs.length; i++) {
recs[i].draw();
recs[i].move();
}
if (StdDraw.mousePressed()) {
for (int i = 0; i < recs.length; i++) {
double x = StdDraw.mouseX();
double y = StdDraw.mouseY();
if (recs[i].containsPoint(x, y)) {
recs[i].setFrozen(true);
}
}
}
for (int i = 0; i < recs.length; i++) {
//for 0
if(recs[0].isFrozen() && recs[0].isIntersecting(recs[1])){
recs[0].setFrozen(false);
}
if(recs[0].isFrozen() && recs[0].isIntersecting(recs[2])){
recs[0].setFrozen(false);
}
if(recs[0].isFrozen() && recs[0].isIntersecting(recs[3])){
recs[0].setFrozen(false);
}
//for 1
if(recs[1].isFrozen() && recs[1].isIntersecting(recs[2])){
recs[1].setFrozen(false);
}
if(recs[1].isFrozen() && recs[1].isIntersecting(recs[3])){
recs[1].setFrozen(false);
}
if(recs[1].isFrozen() && recs[1].isIntersecting(recs[4])){
recs[1].setFrozen(false);
}
//for 2
if(recs[2].isFrozen() && recs[2].isIntersecting(recs[0])){
recs[2].setFrozen(false);
}
if(recs[2].isFrozen() && recs[2].isIntersecting(recs[1])){
recs[2].setFrozen(false);
}
if(recs[2].isFrozen() && recs[2].isIntersecting(recs[3])){
recs[2].setFrozen(false);
}
if(recs[2].isFrozen() && recs[2].isIntersecting(recs[4])){
recs[2].setFrozen(false);
}
//for 3
if(recs[3].isFrozen() && recs[3].isIntersecting(recs[0])){
recs[3].setFrozen(false);
}
if(recs[3].isFrozen() && recs[3].isIntersecting(recs[1])){
recs[3].setFrozen(false);
}
if(recs[3].isFrozen() && recs[3].isIntersecting(recs[2])){
recs[3].setFrozen(false);
}
if(recs[3].isFrozen() && recs[3].isIntersecting(recs[4])){
recs[3].setFrozen(false);
}
//for 4
if(recs[4].isFrozen() && recs[4].isIntersecting(recs[0])){
recs[4].setFrozen(false);
}
if(recs[4].isFrozen() && recs[4].isIntersecting(recs[1])){
recs[4].setFrozen(false);
}
if(recs[4].isFrozen() && recs[4].isIntersecting(recs[3])){
recs[4].setFrozen(false);
}
if(recs[4].isFrozen() && recs[4].isIntersecting(recs[2]))
recs[4].setFrozen(false);
}
if (recs[0].isFrozen() && recs[1].isFrozen() &&
recs[2].isFrozen() && recs[3].isFrozen()
&& recs[4].isFrozen()) {
StdDraw.text(400, 400, "YOU WIN");
}
StdDraw.show(20);
}
}
}
Keep in mind you're using the OR operator here. So if right is less than rLeft, your intersector will return true. This isn't how it should work.
You need to check if right is INSIDE the rectangles bounds so to speak.
if(right <= rRight && right >= rLeft || the other checks here)
The above code checks if right is less than the rectangle's right, but also that the right is bigger than rectangle's left, which means it's somewhere in middle of the rectangle's left and right.
If this becomes too complicated you can simply use java's rectangle class, as it has the methods contains and intersects

how to make my reset button work

I'm writing a code which generates a random maze, every time i run the program it looks diffrent, but i cant get my reset button working. Here is some of my code:
public class MakeFrame extends JPanel implements ActionListener {
JFrame frame;
JPanel buttonPanel;
JButton solve1;
JButton solve2;
JButton solve3;
JButton clear;
JButton reset;
Maze maze = new Maze();
void buildframe() {
frame = new JFrame("maze"); //makes a frame, names it maze
frame.add(this, BorderLayout.CENTER);
frame.add(maze);
buttonPanel = new JPanel();
frame.add(buttonPanel, BorderLayout.NORTH);
solve1 = new JButton("solve 1"); // create some buttons
solve2 = new JButton("solve 2");
solve3 = new JButton("solve 3");
clear = new JButton("clear");
reset = new JButton("reset");
buttonPanel.add(solve1); // add the buttons to a panel
buttonPanel.add(solve2);
buttonPanel.add(solve3);
buttonPanel.add(clear);
buttonPanel.add(reset);
solve1.addActionListener(this);// assigns action listeners to buttons
solve2.addActionListener(this);
solve3.addActionListener(this);
clear.addActionListener(this);
reset.addActionListener(this);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // makes the frame visable, grey and close on exit.
frame.setSize(455, 320);
frame.setVisible(true);
setBackground(Color.GRAY);
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == reset) {
frame.add(new Maze());
repaint();
}
}
}
I don't know what to put in the action performed method to make it work, can anybody help me?
here is my class maze:
public class Maze extends JPanel {
Cell[][] cells = new Cell[22][12];
String[][] route = new String[22][12];
Random random = new Random();
Maze() {
othersetroute();
createFloor();
createWalls();
setStartEnd();
}
void othersetroute() {
int x = 1;
int y = 1;
int downorright;
for (int i = 0; i < 50; i++) {
downorright = random.nextInt(3);
if (x == 20 && y == 10) {
break;
}
if (x > 20 || y > 10) {
break;
}
if (y == 10 || downorright == 0 || downorright == 1) {
x++;
} else {
y++;
}
route[x][y] = "floor";
}
for (int a = 0; a < 22; a++) {
for (int b = 0; b < 12; b++) {
if (route[a][b] == null) {
int floororwall;
floororwall = random.nextInt(4);
if (floororwall == 0 || floororwall == 1) {
route[a][b] = "walls";
} else {
route[a][b] = "floor";
}
if (a % 2 == 1 && b % 2 == 1) {
route[a][b] = "floor";
}
if (a % 2 == 0 && b % 2 == 0) {
route[a][b] = "walls";
}
}
}
}
}
void setRoute() {
int x = 1;
int y = 1;
int leftcounter = 0;
int rightcounter = 0;
int upcounter = 0;
int downcounter = 0;
for (int i = 0; i < 150; i++) {
String direction;
if (x > 20 || y > 10) {
break;
} else if (x == 20 && y == 10) {
break;
} else if (downcounter == 14 && upcounter == 5 && leftcounter == 10 && rightcounter == 29) {
break;
} else if (x == 20) {
int k = random.nextInt(3);
if (k == 0) {
direction = "left";
} else if (k == 1) {
direction = "up";
} else {
direction = "down";
}
} else if (y == 10) {
int k = random.nextInt(3);
if (k == 0) {
direction = "left";
} else if (k == 1) {
direction = "up";
} else {
direction = "right";
}
} else if (x == 1 || y == 1) {
int k = random.nextInt(3);
if (k == 0) {
direction = "down";
} else {
direction = "right";
}
} else {
int k = random.nextInt(4);
if (k == 0) {
direction = "left";
} else if (k == 1) {
direction = "up";
} else if (k == 2) {
direction = "right";
} else {
direction = "down";
}
}
if (direction.equals("right") && rightcounter < 30) {
x++;
rightcounter++;
} else if (direction.equals("down") && downcounter < 15) {
y++;
downcounter++;
} else if (direction.equals("left") && leftcounter < 11) {
x = x - 1;
leftcounter++;
} else if (direction.equals("up") && upcounter < 6) {
y = y - 1;
upcounter++;
}
System.out.println(x);
System.out.println(y);
route[x][y] = "floor";
}
for (int a = 0; a < 22; a++) {
for (int b = 0; b < 12; b++) {
if (route[a][b] == null) {
int floororwall;
floororwall = random.nextInt(4);
if (floororwall == 0 || floororwall == 1) {
route[a][b] = "walls";
} else {
route[a][b] = "floor";
}
if (a % 2 == 1 && b % 2 == 1) {
route[a][b] = "floor";
}
if (a % 2 == 0 && b % 2 == 0) {
route[a][b] = "walls";
}
}
}
}
}
void createFloor() {
for (int x = 0; x < 22; x++) {
for (int y = 0; y < 12; y++) {
if (route[x][y].equals("walls")) {
cells[x][y] = new Cell("walls");
}
if (route[x][y].equals("floor")) {
cells[x][y] = new Cell("floor");
}
}
}
}
void createWalls() {
for (int i = 0; i < 12; i++) {
cells[0][i] = new Cell("walls");
cells[21][i] = new Cell("walls");
}
for (int i = 0; i < 22; i++) {
cells[i][0] = new Cell("walls");
cells[i][11] = new Cell("walls");
}
for (int x = 0; x < 22; x++) {
for (int y = 0; y < 12; y++) {
if (cells[x][y] == null) {
cells[x][y] = new Cell("walls");
}
}
}
}
void setStartEnd() {
cells[1][1] = new Cell("start");
cells[20][10] = new Cell("end");
}
#Override
public void paintComponent(Graphics g) {
for (int x = 0; x < 22; x++) {
for (int y = 0; y < 12; y++) {
if (cells[x][y].getType().equals("#")) {
g.setColor(Color.GREEN);
g.fillRect(x * 20, y * 20, x * 20 + 20, y * 20 + 20);
}
if (cells[x][y].getType().equals(" ")) {
g.setColor(Color.WHITE);
g.fillRect(x * 20, y * 20, x * 20 + 20, y * 20 + 20);
}
if (cells[x][y].getType().equals("S") || cells[x][y].getType().equals("E")) {
g.setColor(Color.PINK);
g.fillRect(x * 20, y * 20, x * 20 + 20, y * 20 + 20);
}
}
}
}
void solutionOne(){ // least visited
int visits[][]= new int [20][10];
for (int i = 0; i<21; i++){
for (int j = 0; j<10; j++){
visits[i][j]=0;
}
}
for (int i = 0; i<100; i++){
}
}
}
and here is my class cell :p
public class Cell {
private String cell;
Cell(String type){
if (type.equals("walls")){
walls();
}
if (type.equals("floor")){
Floor();
}
if (type.equals("start")){
start();
}
if(type.equals("end")){
end();
}
}
void walls(){
cell = "#";
}
void start(){
cell = "S";
}
void end(){
cell = "E";
}
void Floor(){
cell = " ";
}
public String getType(){
return cell;
}
}
You had too much of this
MakeFrame extends JPanel
Which would make another JPanel but I could not find any main methods that ran the whole code, so here you go, enjoy xD
MakeFrame.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MakeFrame extends JFrame implements ActionListener{
JPanel buttonPanel;
JButton solve1;
JButton solve2;
JButton solve3;
JButton clear;
JButton reset;
Maze maze;
public MakeFrame(){
super("Maze");
init();
}
public void init() {
//makes a frame, names it maze
maze = new Maze();
super.getContentPane().add(maze, BorderLayout.CENTER);
buttonPanel = new JPanel();
super.getContentPane().add(buttonPanel, BorderLayout.NORTH);
solve1 = new JButton("solve 1"); // create some buttons
solve2 = new JButton("solve 2");
solve3 = new JButton("solve 3");
clear = new JButton("clear");
reset = new JButton("reset");
buttonPanel.add(solve1); // add the buttons to a panel
buttonPanel.add(solve2);
buttonPanel.add(solve3);
buttonPanel.add(clear);
buttonPanel.add(reset);
solve1.addActionListener(this);// assigns action listeners to buttons
solve2.addActionListener(this);
solve3.addActionListener(this);
clear.addActionListener(this);
reset.addActionListener(this);
super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// makes the frame visable, grey and close on exit.
super.setSize(455, 320);
super.setVisible(true);
super.setBackground(Color.GRAY);
}
public void repaint(){
init();
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == reset) {
super.getContentPane().removeAll();
repaint();
}
}
}
TestMaze.java
public class TestMaze {
public static void main(String [] args){
new MakeFrame();
}
}
private void b2ActionPerformed(java.awt.event.ActionEvent evt) {
jTextField.getText(");
}

GridView Rearange switch by drag and drop

I have a program that creates a Grid and rearranges it by drag-and-droping, first of all everything is functional BUT not the way I wanted it. The must common rearrange is this, you drag an object and when you drop it falls into that position moving all the rest forward until they find the empty space, what I want is more simple; I want the objects to switch with the one that's in the position you dropped it. This is the code of the adapter:
#SuppressLint("WrongCall")
public class DragGridView extends ViewGroup implements View.OnTouchListener,
View.OnClickListener, View.OnLongClickListener {
public static float childRatio = .9f;
protected int colCount, childSize, padding, dpi, scroll = 0;
protected float lastDelta = 0;
protected Handler handler = new Handler();
protected int dragged = -1, lastX = -1, lastY = -1, lastTarget = -1;
protected boolean enabled = true, touching = false;
public static int animT = 150;
protected ArrayList<Integer> newPositions = new ArrayList<Integer>();
protected OnRearrangeListener onRearrangeListener;
protected OnClickListener secondaryOnClickListener;
private OnItemClickListener onItemClickListener;
public interface OnRearrangeListener {
public abstract void onRearrange(int oldIndex, int newIndex);
}
public DragGridView(Context context, AttributeSet attrs) {
super(context, attrs);
setListeners();
handler.removeCallbacks(updateTask);
handler.postAtTime(updateTask, SystemClock.uptimeMillis() + 500);
setChildrenDrawingOrderEnabled(true);
DisplayMetrics metrics = new DisplayMetrics();
((Activity) context).getWindowManager().getDefaultDisplay()
.getMetrics(metrics);
dpi = metrics.densityDpi;
}
protected void setListeners() {
setOnTouchListener(this);
super.setOnClickListener(this);
setOnLongClickListener(this);
}
#Override
public void setOnClickListener(OnClickListener l) {
secondaryOnClickListener = l;
}
protected Runnable updateTask = new Runnable() {
public void run() {
if (dragged != -1) {
if (lastY < padding * 3 && scroll > 0)
scroll -= 20;
else if (lastY > getBottom() - getTop() - (padding * 3)
&& scroll < getMaxScroll())
scroll += 20;
} else if (lastDelta != 0 && !touching) {
scroll += lastDelta;
lastDelta *= .9;
if (Math.abs(lastDelta) < .25)
lastDelta = 0;
}
clampScroll();
onLayout(true, getLeft(), getTop(), getRight(), getBottom());
handler.postDelayed(this, 25);
}
};
#Override
public void addView(View child) {
super.addView(child);
newPositions.add(-1);
};
#Override
public void removeViewAt(int index) {
super.removeViewAt(index);
newPositions.remove(index);
};
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// compute width of view, in dp
float w = (r - l) / (dpi / 160f);
colCount = 2;
int sub = 240;
w -= 280;
while (w > 0) {
colCount++;
w -= sub;
sub += 40;
}
childSize = (r - l) / colCount;
childSize = Math.round(childSize * childRatio);
padding = ((r - l) - (childSize * colCount)) / (colCount + 1);
for (int i = 0; i < getChildCount(); i++)
if (i != dragged) {
Point xy = getCoorFromIndex(i);
getChildAt(i).layout(xy.x, xy.y, xy.x + childSize,
xy.y + childSize);
}
}
#Override
protected int getChildDrawingOrder(int childCount, int i) {
if (dragged == -1)
return i;
else if (i == childCount - 1)
return dragged;
else if (i >= dragged)
return i + 1;
return i;
}
public int getIndexFromCoor(int x, int y) {
int col = getColOrRowFromCoor(x), row = getColOrRowFromCoor(y + scroll);
if (col == -1 || row == -1)
return -1;
int index = row * colCount + col;
if (index >= getChildCount())
return -1;
return index;
}
protected int getColOrRowFromCoor(int coor) {
coor -= padding;
for (int i = 0; coor > 0; i++) {
if (coor < childSize)
return i;
coor -= (childSize + padding);
}
return -1;
}
protected int getTargetFromCoor(int x, int y) {
if (getColOrRowFromCoor(y + scroll) == -1)
return -1;
int leftPos = getIndexFromCoor(x - (childSize / 4), y);
int rightPos = getIndexFromCoor(x + (childSize / 4), y);
if (leftPos == -1 && rightPos == -1)
return -1;
if (leftPos == rightPos)
return -1;
int target = -1;
if (rightPos > -1)
target = rightPos;
else if (leftPos > -1)
target = leftPos + 1;
if (dragged < target)
return target - 1;
return target;
}
protected Point getCoorFromIndex(int index) {
int col = index % colCount;
int row = index / colCount;
return new Point(padding + (childSize + padding) * col, padding
+ (childSize + padding) * row - scroll);
}
public int getIndexOf(View child) {
for (int i = 0; i < getChildCount(); i++)
if (getChildAt(i) == child)
return i;
return -1;
}
public void onClick(View view) {
if (enabled) {
if (secondaryOnClickListener != null)
secondaryOnClickListener.onClick(view);
if (onItemClickListener != null && getLastIndex() != -1)
onItemClickListener.onItemClick(null,
getChildAt(getLastIndex()), getLastIndex(),
getLastIndex() / colCount);
}
}
public boolean onLongClick(View view) {
if (!enabled)
return false;
int index = getLastIndex();
if (index != -1) {
dragged = index;
animateDragged();
return true;
}
return false;
}
#SuppressLint("WrongCall")
public boolean onTouch(View view, MotionEvent event) {
int action = event.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
enabled = true;
lastX = (int) event.getX();
lastY = (int) event.getY();
touching = true;
break;
case MotionEvent.ACTION_MOVE:
int delta = lastY - (int) event.getY();
if (dragged != -1) {
// change draw location of dragged visual
int x = (int) event.getX(), y = (int) event.getY();
int l = x - (3 * childSize / 4), t = y - (3 * childSize / 4);
getChildAt(dragged).layout(l, t, l + (childSize * 3 / 2),
t + (childSize * 3 / 2));
// check for new target hover
int target = getTargetFromCoor(x, y);
if (lastTarget != target) {
if (target != -1) {
animateGap(target);
lastTarget = target;
}
}
} else {
scroll += delta;
clampScroll();
if (Math.abs(delta) > 2)
enabled = false;
onLayout(true, getLeft(), getTop(), getRight(), getBottom());
}
lastX = (int) event.getX();
lastY = (int) event.getY();
lastDelta = delta;
break;
case MotionEvent.ACTION_UP:
if (dragged != -1) {
View v = getChildAt(dragged);
if (lastTarget != -1)
reorderChildren();
else {
Point xy = getCoorFromIndex(dragged);
v.layout(xy.x, xy.y, xy.x + childSize, xy.y + childSize);
}
v.clearAnimation();
if (v instanceof ImageView)
((ImageView) v).setAlpha(255);
lastTarget = -1;
dragged = -1;
}
touching = false;
break;
}
if (dragged != -1)
return true;
return false;
}
protected void animateDragged() {
View v = getChildAt(dragged);
int x = getCoorFromIndex(dragged).x + childSize / 2, y = getCoorFromIndex(dragged).y
+ childSize / 2;
int l = x - (3 * childSize / 4), t = y - (3 * childSize / 4);
v.layout(l, t, l + (childSize * 3 / 2), t + (childSize * 3 / 2));
AnimationSet animSet = new AnimationSet(true);
ScaleAnimation scale = new ScaleAnimation(.667f, 1, .667f, 1,
childSize * 3 / 4, childSize * 3 / 4);
scale.setDuration(animT);
AlphaAnimation alpha = new AlphaAnimation(1, .5f);
alpha.setDuration(animT);
animSet.addAnimation(scale);
animSet.addAnimation(alpha);
animSet.setFillEnabled(true);
animSet.setFillAfter(true);
v.clearAnimation();
v.startAnimation(animSet);
}
protected void animateGap(int target) {
for (int i = 0; i < getChildCount(); i++) {
View v = getChildAt(i);
if (i == dragged)
continue;
int newPos = i;
if (dragged < target && i >= dragged + 1 && i <= target)
newPos--;
else if (target < dragged && i >= target && i < dragged)
newPos++;
int oldPos = i;
if (newPositions.get(i) != -1)
oldPos = newPositions.get(i);
if (oldPos == newPos)
continue;
Point oldXY = getCoorFromIndex(oldPos);
Point newXY = getCoorFromIndex(newPos);
Point oldOffset = new Point(oldXY.x - v.getLeft(), oldXY.y
- v.getTop());
Point newOffset = new Point(newXY.x - v.getLeft(), newXY.y
- v.getTop());
TranslateAnimation translate = new TranslateAnimation(
Animation.ABSOLUTE, oldOffset.x, Animation.ABSOLUTE,
newOffset.x, Animation.ABSOLUTE, oldOffset.y,
Animation.ABSOLUTE, newOffset.y);
translate.setDuration(animT);
translate.setFillEnabled(true);
translate.setFillAfter(true);
v.clearAnimation();
v.startAnimation(translate);
newPositions.set(i, newPos);
}
}
protected void reorderChildren() {
if (onRearrangeListener != null)
onRearrangeListener.onRearrange(dragged, lastTarget);
ArrayList<View> children = new ArrayList<View>();
for (int i = 0; i < getChildCount(); i++) {
getChildAt(i).clearAnimation();
children.add(getChildAt(i));
}
removeAllViews();
while (dragged != lastTarget)
if (lastTarget == children.size())
{
children.add(children.remove(dragged));
dragged = lastTarget;
} else if (dragged < lastTarget)
{
Collections.swap(children, dragged, dragged + 1);
dragged++;
} else if (dragged > lastTarget)
{
Collections.swap(children, dragged, dragged - 1);
dragged--;
}
for (int i = 0; i < children.size(); i++) {
newPositions.set(i, -1);
addView(children.get(i));
}
onLayout(true, getLeft(), getTop(), getRight(), getBottom());
}
#SuppressLint("WrongCall")
public void scrollToTop() {
scroll = 0;
}
public void scrollToBottom() {
scroll = Integer.MAX_VALUE;
clampScroll();
}
protected void clampScroll() {
int stretch = 3, overreach = getHeight() / 2;
int max = getMaxScroll();
max = Math.max(max, 0);
if (scroll < -overreach) {
scroll = -overreach;
lastDelta = 0;
} else if (scroll > max + overreach) {
scroll = max + overreach;
lastDelta = 0;
} else if (scroll < 0) {
if (scroll >= -stretch)
scroll = 0;
else if (!touching)
scroll -= scroll / stretch;
} else if (scroll > max) {
if (scroll <= max + stretch)
scroll = max;
else if (!touching)
scroll += (max - scroll) / stretch;
}
}
protected int getMaxScroll() {
int rowCount = (int) Math.ceil((double) getChildCount() / colCount), max = rowCount
* childSize + (rowCount + 1) * padding - getHeight();
return max;
}
public int getLastIndex() {
return getIndexFromCoor(lastX, lastY);
}
public void setOnRearrangeListener(OnRearrangeListener l) {
this.onRearrangeListener = l;
}
public void setOnItemClickListener(OnItemClickListener l) {
this.onItemClickListener = l;
}
}
The Methods I think I have to change are AnimateGap and reorderChildren, but don't know how to do it exactly.

Constant Width SashForm

My application has a SashForm with two children. I want the left child to stay the same size when the window is resized. I want the same thing Eclipse does with the Package Explorer and the main editor. When you resize the window only the text editor changes size. However, the Package Explorer is still resizeable by the sash.
I tried using the following
sashForm.addControlListener(new ControlAdapter() {
#Override
public void controlResized(ControlEvent e) {
int width = sashForm.getClientArea().width;
int[] weights = sashForm.getWeights();
weights[1] = width - weights[0];
sashForm.setWeights(weights);
}
});
The problem is the width of the left size either shrinks to 0 or expands too much. It looks like the weights are updated before this is called or something.
If I set weights[0] equal to some constant it does what I want.
I managed to get an example running that should give you an idea how to solve your problem. The thing is, that the SashForm uses weights rather than pixels. So you have to compute the percentage the left child has to occupy based on the parent size and assign the rest to the right child.
In my code example, you can specify the width of the left child and set a minimal size for the right child, such that the SashForm will always show both.
private static final int MIN_WIDTH_LEFT = 100;
private static final int MIN_WIDTH_RIGHT = 50;
public static void main(String[] args)
{
Display display = new Display();
final Shell shell = new Shell(display);
shell.setText("StackOverflow");
shell.setLayout(new FillLayout());
final SashForm form = new SashForm(shell, SWT.HORIZONTAL);
Button button = new Button(form, SWT.PUSH);
button.setText("Left");
Button buttonR = new Button(form, SWT.PUSH);
buttonR.setText("Right");
form.setWeights(new int[] {1, 2});
shell.addListener(SWT.Resize, new Listener()
{
#Override
public void handleEvent(Event arg0)
{
int width = shell.getClientArea().width;
int[] weights = form.getWeights();
if(width >= MIN_WIDTH_LEFT + MIN_WIDTH_RIGHT)
{
weights[0] = 1000000 * MIN_WIDTH_LEFT / width;
weights[1] = 1000000 - weights[0];
}
else
{
weights[0] = 1000000 * MIN_WIDTH_LEFT / (MIN_WIDTH_LEFT + MIN_WIDTH_RIGHT);
weights[1] = 1000000 * MIN_WIDTH_RIGHT / (MIN_WIDTH_LEFT + MIN_WIDTH_RIGHT);
}
System.out.println(width + " " + Arrays.toString(weights));
form.setWeights(weights);
}
});
shell.pack();
shell.setSize(600, 400);
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
This is what it looks like:
Startup:
After resizing:
When decreasing the window size until it is too small to show both minimal sizes:
As you can see in this case, the minimal size for the left child is ignored to still be able to show both childs.
This is the best solution I could come up with.
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
public class Main {
private static int leftWidth, oldWeight;
public static void main(String[] args) {
Display display = new Display();
final Shell shell = new Shell(display);
shell.setText("StackOverflow");
shell.setLayout(new FillLayout());
shell.setSize(600, 400);
final SashForm form = new SashForm(shell, SWT.HORIZONTAL);
final Button button = new Button(form, SWT.PUSH);
button.setText("Left");
button.addListener(SWT.Resize, new Listener() {
#Override
public void handleEvent(Event arg0) {
int[] weights = form.getWeights();
// oldWeights is used to distinguish between a window resize and
// a sash move
if (oldWeight != weights[0]) {
System.out.println("Weights changed!");
oldWeight = weights[0];
leftWidth = (int) Math.round((double) form.getClientArea().width
* (double) weights[0]
/ (double) (weights[0] + weights[1]));
}
}
});
Button buttonR = new Button(form, SWT.PUSH);
buttonR.setText("Right");
form.setWeights(new int[] { 200, 800 });
leftWidth = 200;
form.addListener(SWT.Resize, new Listener() {
#Override
public void handleEvent(Event arg0) {
int width = form.getClientArea().width;
int[] weights = form.getWeights();
double perChange = (double) leftWidth / (double) width;
weights[0] = (int) (perChange * 1000.0);
weights[1] = 1000 - weights[0];
// oldWeights must be set before form.setWeights
oldWeight = weights[0];
form.setWeights(weights);
}
});
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
The sash jumps around about 1px when the window is resized due to rounding issues, but it seems to do what I want.
This is a very hacky solution and I would like to know if there is a better one. It also crashes if you make the window smaller than the left button, but that is easy to fix.
Have to rewrite SashForm to get this behavior. new SashForm(Composite parent, int style) is old behavior; new SashForm(Composite parent, int style, false) uses widths/heights specified in pixels.
Not tested with more than two Composite children of the SashForm, and odd behavior if you don't setLength when using new behavior, but will not break existing uses of SashForm
e.g.:
public static void main(String[] args)
{
Display display = new Display();
final Shell shell = new Shell(display);
shell.setText("StackOverflow");
shell.setLayout(new FillLayout());
final SashForm form = new SashForm(shell, SWT.HORIZONTAL);
Button button = new Button(form, SWT.PUSH);
button.setText("Left");
Button buttonR = new Button(form, SWT.PUSH);
buttonR.setText("Right");
form.setLengths(new int[] { 250, 25 });
shell.pack();
shell.setSize(600, 400);
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
First button will default to 250 pixels, second the remainder shell
SashForm.java:
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.graphics.*;
public class SashForm extends Composite {
/**
* The width of all sashes in the form.
*/
public int SASH_WIDTH = 3;
int sashStyle;
final private boolean weighted;
Sash[] sashes = new Sash[0];
// Remember background and foreground
// colors to determine whether to set
// sashes to the default color (null) or
// a specific color
Color background = null;
Color foreground = null;
Control[] controls = new Control[0];
Control maxControl = null;
Listener sashListener;
static final int DRAG_MINIMUM = 20;
public SashForm(Composite parent, int style) {
super(parent, checkStyle(style));
super.setLayout(new SashFormLayout());
sashStyle = ((style & SWT.VERTICAL) != 0) ? SWT.HORIZONTAL : SWT.VERTICAL;
if ((style & SWT.BORDER) != 0) sashStyle |= SWT.BORDER;
if ((style & SWT.SMOOTH) != 0) sashStyle |= SWT.SMOOTH;
sashListener = new Listener() {
public void handleEvent(Event e) {
onDragSash(e);
}
};
weighted = true;
}
public SashForm(Composite parent, int style, boolean weighted) {
super(parent, checkStyle(style));
super.setLayout(new SashFormLayout());
sashStyle = ((style & SWT.VERTICAL) != 0) ? SWT.HORIZONTAL : SWT.VERTICAL;
if ((style & SWT.BORDER) != 0) sashStyle |= SWT.BORDER;
if ((style & SWT.SMOOTH) != 0) sashStyle |= SWT.SMOOTH;
sashListener = new Listener() {
public void handleEvent(Event e) {
onDragSash(e);
}
};
this.weighted = weighted;
}
static int checkStyle (int style) {
int mask = SWT.BORDER | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
return style & mask;
}
Sash createSash() {
Sash sash = new Sash(this, sashStyle);
sash.setBackground(background);
sash.setForeground(foreground);
sash.setToolTipText(getToolTipText());
sash.addListener(SWT.Selection, sashListener);
return sash;
}
#Override
public int getOrientation() {
//checkWidget();
return (sashStyle & SWT.VERTICAL) != 0 ? SWT.HORIZONTAL : SWT.VERTICAL;
}
/**
* Returns the width of the sashes when the controls in the SashForm are
* laid out.
*
* #return the width of the sashes
*
* #exception SWTException <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
* </ul>
*
* #since 3.4
*/
public int getSashWidth() {
checkWidget();
return SASH_WIDTH;
}
#Override
public int getStyle() {
int style = super.getStyle();
style |= getOrientation() == SWT.VERTICAL ? SWT.VERTICAL : SWT.HORIZONTAL;
if ((sashStyle & SWT.SMOOTH) != 0) style |= SWT.SMOOTH;
return style;
}
/**
* Answer the control that currently is maximized in the SashForm.
* This value may be null.
*
* #return the control that currently is maximized or null
*/
public Control getMaximizedControl(){
//checkWidget();
return this.maxControl;
}
public int[] getWeights() {
checkWidget();
Control[] cArray = getControls(false);
int[] ratios = new int[cArray.length];
for (int i = 0; i < cArray.length; i++) {
Object data = cArray[i].getLayoutData();
if (data != null && data instanceof SashFormData) {
ratios[i] = (int)(((SashFormData)data).weight * 1000 >> 16);
} else {
ratios[i] = 200;
}
}
return ratios;
}
Control[] getControls(boolean onlyVisible) {
Control[] children = getChildren();
Control[] result = new Control[0];
for (int i = 0; i < children.length; i++) {
if (children[i] instanceof Sash) continue;
if (onlyVisible && !children[i].getVisible()) continue;
Control[] newResult = new Control[result.length + 1];
System.arraycopy(result, 0, newResult, 0, result.length);
newResult[result.length] = children[i];
result = newResult;
}
return result;
}
boolean getWeighted() {
return weighted;
}
void onDragSash(Event event) {
Sash sash = (Sash)event.widget;
int sashIndex = -1;
for (int i= 0; i < sashes.length; i++) {
if (sashes[i] == sash) {
sashIndex = i;
break;
}
}
if (sashIndex == -1) return;
Control c1 = controls[sashIndex];
Control c2 = controls[sashIndex + 1];
Rectangle b1 = c1.getBounds();
Rectangle b2 = c2.getBounds();
Rectangle sashBounds = sash.getBounds();
Rectangle area = getClientArea();
boolean correction = false;
if (getOrientation() == SWT.HORIZONTAL) {
correction = b1.width < DRAG_MINIMUM || b2.width < DRAG_MINIMUM;
int totalWidth = b2.x + b2.width - b1.x;
int shift = event.x - sashBounds.x;
b1.width += shift;
b2.x += shift;
b2.width -= shift;
if (b1.width < DRAG_MINIMUM) {
b1.width = DRAG_MINIMUM;
b2.x = b1.x + b1.width + sashBounds.width;
b2.width = totalWidth - b2.x;
event.x = b1.x + b1.width;
event.doit = false;
}
if (b2.width < DRAG_MINIMUM) {
b1.width = totalWidth - DRAG_MINIMUM - sashBounds.width;
b2.x = b1.x + b1.width + sashBounds.width;
b2.width = DRAG_MINIMUM;
event.x = b1.x + b1.width;
event.doit = false;
}
Object data1 = c1.getLayoutData();
if (data1 == null || !(data1 instanceof SashFormData)) {
data1 = new SashFormData();
c1.setLayoutData(data1);
}
Object data2 = c2.getLayoutData();
if (data2 == null || !(data2 instanceof SashFormData)) {
data2 = new SashFormData();
c2.setLayoutData(data2);
}
((SashFormData)data1).weight = (((long)b1.width << 16) + area.width - 1) / area.width;
((SashFormData)data1).length = b1.width;
((SashFormData)data2).weight = (((long)b2.width << 16) + area.width - 1) / area.width;
((SashFormData)data2).length = b2.width;
} else {
correction = b1.height < DRAG_MINIMUM || b2.height < DRAG_MINIMUM;
int totalHeight = b2.y + b2.height - b1.y;
int shift = event.y - sashBounds.y;
b1.height += shift;
b2.y += shift;
b2.height -= shift;
if (b1.height < DRAG_MINIMUM) {
b1.height = DRAG_MINIMUM;
b2.y = b1.y + b1.height + sashBounds.height;
b2.height = totalHeight - b2.y;
event.y = b1.y + b1.height;
event.doit = false;
}
if (b2.height < DRAG_MINIMUM) {
b1.height = totalHeight - DRAG_MINIMUM - sashBounds.height;
b2.y = b1.y + b1.height + sashBounds.height;
b2.height = DRAG_MINIMUM;
event.y = b1.y + b1.height;
event.doit = false;
}
Object data1 = c1.getLayoutData();
if (data1 == null || !(data1 instanceof SashFormData)) {
data1 = new SashFormData();
c1.setLayoutData(data1);
}
Object data2 = c2.getLayoutData();
if (data2 == null || !(data2 instanceof SashFormData)) {
data2 = new SashFormData();
c2.setLayoutData(data2);
}
((SashFormData)data1).weight = (((long)b1.height << 16) + area.height - 1) / area.height;
((SashFormData)data2).weight = (((long)b2.height << 16) + area.height - 1) / area.height;
}
if (correction || (event.doit && event.detail != SWT.DRAG)) {
c1.setBounds(b1);
sash.setBounds(event.x, event.y, event.width, event.height);
c2.setBounds(b2);
}
}
#Override
public void setOrientation(int orientation) {
checkWidget();
if (orientation == SWT.RIGHT_TO_LEFT || orientation == SWT.LEFT_TO_RIGHT) {
super.setOrientation(orientation);
return;
}
if (getOrientation() == orientation) return;
if (orientation != SWT.HORIZONTAL && orientation != SWT.VERTICAL) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
sashStyle &= ~(SWT.HORIZONTAL | SWT.VERTICAL);
sashStyle |= orientation == SWT.VERTICAL ? SWT.HORIZONTAL : SWT.VERTICAL;
for (int i = 0; i < sashes.length; i++) {
sashes[i].dispose();
sashes[i] = createSash();
}
layout(false);
}
#Override
public void setBackground (Color color) {
super.setBackground(color);
background = color;
for (int i = 0; i < sashes.length; i++) {
sashes[i].setBackground(background);
}
}
#Override
public void setForeground (Color color) {
super.setForeground(color);
foreground = color;
for (int i = 0; i < sashes.length; i++) {
sashes[i].setForeground(foreground);
}
}
#Override
public void setLayout (Layout layout) {
checkWidget();
return;
}
public void setMaximizedControl(Control control){
checkWidget();
if (control == null) {
if (maxControl != null) {
this.maxControl = null;
layout(false);
for (int i= 0; i < sashes.length; i++){
sashes[i].setVisible(true);
}
}
return;
}
for (int i= 0; i < sashes.length; i++){
sashes[i].setVisible(false);
}
maxControl = control;
layout(false);
}
public void setSashWidth(int width) {
checkWidget();
if (SASH_WIDTH == width) return;
SASH_WIDTH = width;
layout(false);
}
#Override
public void setToolTipText(String string) {
super.setToolTipText(string);
for (int i = 0; i < sashes.length; i++) {
sashes[i].setToolTipText(string);
}
}
public void setWeights(int[] weights) {
checkWidget();
Control[] cArray = getControls(false);
if (weights == null || weights.length != cArray.length) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
int total = 0;
for (int i = 0; i < weights.length; i++) {
if (weights[i] < 0) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
total += weights[i];
}
if (total == 0) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
for (int i = 0; i < cArray.length; i++) {
Object data = cArray[i].getLayoutData();
if (data == null || !(data instanceof SashFormData)) {
data = new SashFormData();
cArray[i].setLayoutData(data);
}
((SashFormData)data).weight = (((long)weights[i] << 16) + total - 1) / total;
}
layout(false);
}
public void setLengths(int[] lengths) {
checkWidget();
Control[] cArray = getControls(false);
if (lengths == null || lengths.length != cArray.length) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
int total = 0;
for (int i = 0; i < lengths.length; i++) {
if (lengths[i] < 0) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
total += lengths[i];
}
if (total == 0) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
for (int i = 0; i < cArray.length; i++) {
Object data = cArray[i].getLayoutData();
if (data == null || !(data instanceof SashFormData)) {
data = new SashFormData();
cArray[i].setLayoutData(data);
}
((SashFormData)data).length = lengths[i];
}
layout(false);
}
}
SashFormData.java:
class SashFormData {
long weight;
int length;
String getName () {
String string = getClass ().getName ();
int index = string.lastIndexOf ('.');
if (index == -1) return string;
return string.substring (index + 1, string.length ());
}
#Override
public String toString () {
return getName()+" {length="+length+", weight="+weight+"}"; //$NON-NLS-2$
}
}
SashFormLayout.java:
import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;
class SashFormLayout extends Layout {
#Override
protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
SashForm sashForm = (SashForm)composite;
Control[] cArray = sashForm.getControls(true);
int width = 0;
int height = 0;
if (cArray.length == 0) {
if (wHint != SWT.DEFAULT) width = wHint;
if (hHint != SWT.DEFAULT) height = hHint;
return new Point(width, height);
}
// determine control sizes
boolean vertical = sashForm.getOrientation() == SWT.VERTICAL;
if (sashForm.getWeighted()) {
int maxIndex = 0;
int maxValue = 0;
for (int i = 0; i < cArray.length; i++) {
if (vertical) {
Point size = cArray[i].computeSize(wHint, SWT.DEFAULT, flushCache);
if (size.y > maxValue) {
maxIndex = i;
maxValue = size.y;
}
width = Math.max(width, size.x);
} else {
Point size = cArray[i].computeSize(SWT.DEFAULT, hHint, flushCache);
if (size.x > maxValue) {
maxIndex = i;
maxValue = size.x;
}
height = Math.max(height, size.y);
}
}
// get the ratios
long[] ratios = new long[cArray.length];
long total = 0;
for (int i = 0; i < cArray.length; i++) {
Object data = cArray[i].getLayoutData();
if (data != null && data instanceof SashFormData) {
ratios[i] = ((SashFormData)data).weight;
} else {
data = new SashFormData();
cArray[i].setLayoutData(data);
((SashFormData)data).weight = ratios[i] = ((200 << 16) + 999) / 1000;
}
total += ratios[i];
}
if (ratios[maxIndex] > 0) {
int sashwidth = sashForm.sashes.length > 0 ? sashForm.SASH_WIDTH + sashForm.sashes [0].getBorderWidth() * 2 : sashForm.SASH_WIDTH;
if (vertical) {
height += (int)(total * maxValue / ratios[maxIndex]) + (cArray.length - 1) * sashwidth;
} else {
width += (int)(total * maxValue / ratios[maxIndex]) + (cArray.length - 1) * sashwidth;
}
}
} else {
int maxIndex = 0;
int maxValue = 0;
for (int i = 0; i < cArray.length; i++) {
if (vertical) {
Point size = cArray[i].computeSize(wHint, SWT.DEFAULT, flushCache);
if (size.y > maxValue) {
maxIndex = i;
maxValue = size.y;
}
width = Math.max(width, size.x);
} else {
Point size = cArray[i].computeSize(SWT.DEFAULT, hHint, flushCache);
if (size.x > maxValue) {
maxIndex = i;
maxValue = size.x;
}
height = Math.max(height, size.y);
}
}
// get the lengths
int[] lengths = new int[cArray.length];
long total = 0;
for (int i = 0; i < cArray.length; i++) {
Object data = cArray[i].getLayoutData();
if (data != null && data instanceof SashFormData) {
lengths[i] = ((SashFormData)data).length;
} else {
data = new SashFormData();
cArray[i].setLayoutData(data);
((SashFormData)data).length = sashForm.getOrientation() == SWT.HORIZONTAL ? cArray[i].getSize().x : cArray[i].getSize().y;
}
total += lengths[i];
}
if (lengths[maxIndex] > 0) {
int sashwidth = sashForm.sashes.length > 0 ? sashForm.SASH_WIDTH + sashForm.sashes [0].getBorderWidth() * 2 : sashForm.SASH_WIDTH;
if (vertical) {
height += total + (cArray.length - 1) * sashwidth;
} else {
width += total + (cArray.length - 1) * sashwidth;
}
}
}
width += sashForm.getBorderWidth()*2;
height += sashForm.getBorderWidth()*2;
if (wHint != SWT.DEFAULT) width = wHint;
if (hHint != SWT.DEFAULT) height = hHint;
return new Point(width, height);
}
#Override
protected boolean flushCache(Control control) {
return true;
}
#Override
protected void layout(Composite composite, boolean flushCache) {
SashForm sashForm = (SashForm)composite;
Rectangle area = sashForm.getClientArea();
if (area.width <= 1 || area.height <= 1) return;
Control[] newControls = sashForm.getControls(true);
if (sashForm.controls.length == 0 && newControls.length == 0) return;
sashForm.controls = newControls;
Control[] controls = sashForm.controls;
if (sashForm.maxControl != null && !sashForm.maxControl.isDisposed()) {
for (int i= 0; i < controls.length; i++){
if (controls[i] != sashForm.maxControl) {
controls[i].setBounds(-200, -200, 0, 0);
} else {
controls[i].setBounds(area);
}
}
return;
}
// keep just the right number of sashes
if (sashForm.sashes.length < controls.length - 1) {
Sash[] newSashes = new Sash[controls.length - 1];
System.arraycopy(sashForm.sashes, 0, newSashes, 0, sashForm.sashes.length);
for (int i = sashForm.sashes.length; i < newSashes.length; i++) {
newSashes[i] = sashForm.createSash();
}
sashForm.sashes = newSashes;
}
if (sashForm.sashes.length > controls.length - 1) {
if (controls.length == 0) {
for (int i = 0; i < sashForm.sashes.length; i++) {
sashForm.sashes[i].dispose();
}
sashForm.sashes = new Sash[0];
} else {
Sash[] newSashes = new Sash[controls.length - 1];
System.arraycopy(sashForm.sashes, 0, newSashes, 0, newSashes.length);
for (int i = controls.length - 1; i < sashForm.sashes.length; i++) {
sashForm.sashes[i].dispose();
}
sashForm.sashes = newSashes;
}
}
if (controls.length == 0) return;
Sash[] sashes = sashForm.sashes;
if (sashForm.getWeighted()) {
// get the ratios
long[] ratios = new long[controls.length];
long total = 0;
for (int i = 0; i < controls.length; i++) {
Object data = controls[i].getLayoutData();
if (data != null && data instanceof SashFormData) {
ratios[i] = ((SashFormData)data).weight;
} else {
data = new SashFormData();
controls[i].setLayoutData(data);
((SashFormData)data).weight = ratios[i] = ((200 << 16) + 999) / 1000;
}
total += ratios[i];
}
int sashwidth = sashes.length > 0 ? sashForm.SASH_WIDTH + sashes [0].getBorderWidth() * 2 : sashForm.SASH_WIDTH;
if (sashForm.getOrientation() == SWT.HORIZONTAL) {
int width = (int)(ratios[0] * (area.width - sashes.length * sashwidth) / total);
int x = area.x;
controls[0].setBounds(x, area.y, width, area.height);
x += width;
for (int i = 1; i < controls.length - 1; i++) {
sashes[i - 1].setBounds(x, area.y, sashwidth, area.height);
x += sashwidth;
width = (int)(ratios[i] * (area.width - sashes.length * sashwidth) / total);
controls[i].setBounds(x, area.y, width, area.height);
x += width;
}
if (controls.length > 1) {
sashes[sashes.length - 1].setBounds(x, area.y, sashwidth, area.height);
x += sashwidth;
width = area.width - x;
controls[controls.length - 1].setBounds(x, area.y, width, area.height);
}
} else {
int height = (int)(ratios[0] * (area.height - sashes.length * sashwidth) / total);
int y = area.y;
controls[0].setBounds(area.x, y, area.width, height);
y += height;
for (int i = 1; i < controls.length - 1; i++) {
sashes[i - 1].setBounds(area.x, y, area.width, sashwidth);
y += sashwidth;
height = (int)(ratios[i] * (area.height - sashes.length * sashwidth) / total);
controls[i].setBounds(area.x, y, area.width, height);
y += height;
}
if (controls.length > 1) {
sashes[sashes.length - 1].setBounds(area.x, y, area.width, sashwidth);
y += sashwidth;
height = area.height - y;
controls[controls.length - 1].setBounds(area.x, y, area.width, height);
}
}
} else {
// get the lengths
int[] lengths = new int[controls.length];
for (int i = 0; i < controls.length; i++) {
Object data = controls[i].getLayoutData();
if (data != null && data instanceof SashFormData) {
lengths[i] = ((SashFormData)data).length;
} else {
data = new SashFormData();
controls[i].setLayoutData(data);
((SashFormData)data).length = sashForm.getOrientation() == SWT.HORIZONTAL ? controls[i].getSize().x : controls[i].getSize().y;
}
}
int sashwidth = sashes.length > 0 ? sashForm.SASH_WIDTH + sashes [0].getBorderWidth() * 2 : sashForm.SASH_WIDTH;
if (sashForm.getOrientation() == SWT.HORIZONTAL) {
int width = lengths[0];
int x = area.x;
controls[0].setBounds(x, area.y, width, area.height);
x += width;
for (int i = 1; i < controls.length - 1; i++) {
sashes[i - 1].setBounds(x, area.y, sashwidth, area.height);
x += sashwidth;
width = lengths[i];
controls[i].setBounds(x, area.y, width, area.height);
x += width;
}
if (controls.length > 1) {
sashes[sashes.length - 1].setBounds(x, area.y, sashwidth, area.height);
x += sashwidth;
width = area.width - x;
controls[controls.length - 1].setBounds(x, area.y, width, area.height);
}
} else {
int height = lengths[0];
int y = area.y;
controls[0].setBounds(area.x, y, area.width, height);
y += height;
for (int i = 1; i < controls.length - 1; i++) {
sashes[i - 1].setBounds(area.x, y, area.width, sashwidth);
y += sashwidth;
height = lengths[i];
controls[i].setBounds(area.x, y, area.width, height);
y += height;
}
if (controls.length > 1) {
sashes[sashes.length - 1].setBounds(area.x, y, area.width, sashwidth);
y += sashwidth;
height = area.height - y;
controls[controls.length - 1].setBounds(area.x, y, area.width, height);
}
}
}
}
}

Categories