Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Квадратные компоненты в GridLayout 
V
    Опции темы
_Michael
Дата 13.9.2007, 16:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 375
Регистрация: 23.6.2007
Где: з полонини

Репутация: 1
Всего: 6



Здравствуйте, подскажите пожалуйста. У меня есть JPanel на которой устновлен GridLayout например 13 столбцов и 8 строк. Как мне сделать чтоб размер моей панели был такой чтоб все компонеты добавленные в нее были квадратными? И чтоб ето свойство сохранялось при изменении размера панели. Пробовал имплементировать ComponentListener с таким вот методом:
Код

    public void componentResized(ComponentEvent e) {
        int h = this.getHeight();
// простая пропорция отношения высоты  к шырине как кол-во строк / кол-во столбцов из которой мы определяем новую шырину.
        int w = (h/rows)*columns; 
        setSize(w, h);
    }

но ему все равно.  smile 


--------------------
...не убивайся ни о чем - все временно,
хоть ночь темна но светлым днем беременна...

Саади
PM MAIL   Вверх
dorogoyIV
Дата 14.9.2007, 10:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1503
Регистрация: 26.3.2007

Репутация: 36
Всего: 46



хм, все работает. ты не забыл   addComponentListener(this); ?
PM MAIL   Вверх
_Michael
Дата 14.9.2007, 11:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 375
Регистрация: 23.6.2007
Где: з полонини

Репутация: 1
Всего: 6



нет не забыл. :(. Пробовал выводить в  консоль размер до и после setSize(w, h); И в консоль оно так и выводит, что размер до и после setSize(w, h); не изменился. У меня ета панель добавляется на другую панель на которой установлен BorderLayout, в центр, и соответственно она и растагивается чтоб все место заполнить, т.е имеет приоритет перед етим моим  setSize(w, h); я ето както так понимаю. Но можно ж както ето обойти ведь smile

Добавлено через 2 минуты и 54 секунды
Стоп. или может мой  setSize(w, h); сработал но после него сразу сработал еще один который после него вызывается где то каким то менеджером, наверное тем же Bordelayout'ом на той панели на которой расположена моя с GradLayout?

Это сообщение отредактировал(а) _Michael - 14.9.2007, 11:14


--------------------
...не убивайся ни о чем - все временно,
хоть ночь темна но светлым днем беременна...

Саади
PM MAIL   Вверх
dorogoyIV
Дата 14.9.2007, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1503
Регистрация: 26.3.2007

Репутация: 36
Всего: 46



я сделал панель с GridLayout. положил ее на ContentPane. листенер повесил на фрейм.
и работает!
PM MAIL   Вверх
_Michael
Дата 14.9.2007, 11:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 375
Регистрация: 23.6.2007
Где: з полонини

Репутация: 1
Всего: 6



addComponentListener(this); ето ж не на фрейм как я понимаю а на мою панель. Ну у меня так реализованно. А ты говришь что надо листенер вешать на весь фрейм и в нем изменять размер панели? шас спробую что получится

Добавлено через 4 минуты и 21 секунду
Нет однако мене кажется что так не делается., чтоб в листенере фрейма изменять размер дочерних панелей, а если моя панель на трех других лежит. надо както инче имхо smile


--------------------
...не убивайся ни о чем - все временно,
хоть ночь темна но светлым днем беременна...

Саади
PM MAIL   Вверх
dorogoyIV
Дата 14.9.2007, 11:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1503
Регистрация: 26.3.2007

Репутация: 36
Всего: 46



ну вот грубый набросок
Код

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

class Grid extends JFrame implements ComponentListener
{
 int rows=8;
 int columns=13;
 JPanel jp=new JPanel(new GridLayout(rows,columns,4,4));
 JLabel [] jl=new JLabel [rows*columns];

 Grid()
 {
  setBounds(100,100,400,300);
  add(jp);

  for(int i=0;i<rows*columns;i++)
  {
   jl [i]=new JLabel();
   jl [i].setOpaque(true);
   jl [i].setBackground(Color.GREEN);
   jp.add(jl [i]);
  }

  addComponentListener(this);
 }

 public void componentHidden(ComponentEvent e){}
 public void componentMoved(ComponentEvent e){}
 public void componentShown(ComponentEvent e){}

 public void componentResized(ComponentEvent e)
 {
  int h=getHeight();
  int w=(h/rows)*columns;
  setSize(w,h);
 }

 public static void main(String[]args)
 {
  JFrame f=new Grid();
  f.setVisible(true);
  f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 }
}



Добавлено через 8 минут и 46 секунд
Цитата(_Michael @  14.9.2007,  11:25 Найти цитируемый пост)
Нет однако мене кажется что так не делается.,

а как иначе? будут же изменяться размеры фрейма, значит их и надо слушать
PM MAIL   Вверх
_Michael
Дата 14.9.2007, 15:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 375
Регистрация: 23.6.2007
Где: з полонини

Репутация: 1
Всего: 6



Цитата(dorogoyIV @  14.9.2007,  11:47 Найти цитируемый пост)
а как иначе? будут же изменяться размеры фрейма, значит их и надо слушать 

так можно слушать не рамер фрейма а размер только моей панели на которую листенер и повешать, или нет?

И еще у меня тут вызрела идея, может ето свой LayoutManager наподобе с GridLayout но только с квадратными ячейками. Как понимаю можно наследовать от GridLayout и переопределить один-два метода?

Это сообщение отредактировал(а) _Michael - 14.9.2007, 15:34


--------------------
...не убивайся ни о чем - все временно,
хоть ночь темна но светлым днем беременна...

Саади
PM MAIL   Вверх
dorogoyIV
Дата 14.9.2007, 21:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1503
Регистрация: 26.3.2007

Репутация: 36
Всего: 46



Цитата(_Michael @  14.9.2007,  15:33 Найти цитируемый пост)
так можно слушать не рамер фрейма а размер только моей панели на которую листенер и повешать, или нет?

тогда наверное придется делать самому репейнт

Цитата(_Michael @  14.9.2007,  15:33 Найти цитируемый пост)
свой LayoutManager наподобе с GridLayout но ...

ну да  smile 
PM MAIL   Вверх
_Michael
Дата 15.9.2007, 15:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 375
Регистрация: 23.6.2007
Где: з полонини

Репутация: 1
Всего: 6



Одним словом написать свой LayoutManager  не такая сложная задача как я думал поначале. Вот плод моих творений SquareGridLayout :
Код

import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Insets;

public class SquareGridLayout extends GridLayout {

    private int rows;
    private int cols;
    private int hgap;
    private int vgap;

    public SquareGridLayout() {
        this(1, 0, 0, 0);
    }

    public SquareGridLayout(int rows, int cols) {
        this(rows, cols, 0, 0);
    }

    public SquareGridLayout(int rows, int cols, int hgap, int vgap) {
        if ((rows == 0) && (cols == 0)) {
            throw new IllegalArgumentException("rows and cols cannot both be zero");
        }
        this.rows = rows;
        this.cols = cols;
        this.hgap = hgap;
        this.vgap = vgap;
    }

    public void layoutContainer(Container parent) {
        Insets insets = parent.getInsets();
        int ncomponents = parent.getComponentCount();
        int nrows = rows;
        int ncols = cols;
        boolean ltr = parent.getComponentOrientation().isLeftToRight();

        if (ncomponents == 0) {
            return;
        }
        if (nrows > 0) {
            ncols = (ncomponents + nrows - 1) / nrows;
        } else {
            nrows = (ncomponents + ncols - 1) / ncols;
        }

        int w = parent.getWidth() - (insets.left + insets.right);
        int h = parent.getHeight() - (insets.top + insets.bottom);
        int dx = 0;
        int dy = 0;
        if (w*rows > h*cols) {
            dx = (int)Math.round((w - (double)h*cols/rows) / 2);
            w = h*cols/rows;
            int k = (h - (nrows - 1) * vgap) / nrows;
            dy = (h -k*rows)/2;
            h = k;
            w = (w - (ncols - 1) * hgap) / ncols;
        } else {
            dy = (int)Math.round((h - (double)w*rows/cols) / 2);
            h = w*rows/cols;
            int k = (w - (ncols - 1) * hgap) / ncols;
            dx = (w-k*ncols)/2;
            w = k;
            h = (h - (nrows - 1) * vgap) / nrows;
        }
         w = (w - (ncols - 1) * hgap) / ncols;
        h = (h - (nrows - 1) * vgap) / nrows;
        if (ltr) {
            for (int c = 0, x = insets.left + dx; c < ncols; c++, x += w + hgap) {
                for (int r = 0, y = insets.top + dy; r < nrows; r++, y += h    + vgap) {
                    int i = r * ncols + c;
                    if (i < ncomponents) {
                        parent.getComponent(i).setBounds(x, y, w, h);
                    }
                }
            }
        } else {
            for (int c = 0, x = parent.getWidth() - insets.right - w; c < ncols; c++, x -= w + hgap) {
                for (int r = 0, y = insets.top; r < nrows; r++, y += h + vgap) {
                    int i = r * ncols + c;
                    if (i < ncomponents) {
                        parent.getComponent(i).setBounds(x, y, w, h);
                    }
                }
            }
        }
    }

    public Dimension minimumLayoutSize(Container parent) {
        return super.minimumLayoutSize(parent);
    }

    public Dimension preferredLayoutSize(Container parent) {
        return super.preferredLayoutSize(parent);
    }
}

Если че неясно по коду спрашывайте smile
P.S. тема решена. 
dorogoyIV, спасибо за порявленный интерес и старания smile

Упс, извиняюсь там одна ошибка думаю скоро исправлю

Это сообщение отредактировал(а) _Michael - 15.9.2007, 23:08


--------------------
...не убивайся ни о чем - все временно,
хоть ночь темна но светлым днем беременна...

Саади
PM MAIL   Вверх
_Michael
Дата 15.9.2007, 23:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 375
Регистрация: 23.6.2007
Где: з полонини

Репутация: 1
Всего: 6



Все, исправил. Идеально не получилось поскольку ето связано с ошыбкой округлений, так как полтора пикселя например не можна отмерять или нарисовать. smile


--------------------
...не убивайся ни о чем - все временно,
хоть ночь темна но светлым днем беременна...

Саади
PM MAIL   Вверх
dorogoyIV
Дата 16.9.2007, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1503
Регистрация: 26.3.2007

Репутация: 36
Всего: 46



тогда делай четное число, например так:
Код

if((x%2)==0)
   ...
else
   x+=1;


ой, не то написал  smile 
класс BigDecimal может округлить число например до ближайшего целого

Это сообщение отредактировал(а) dorogoyIV - 16.9.2007, 10:44
PM MAIL   Вверх
dorogoyIV
Дата 16.9.2007, 13:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1503
Регистрация: 26.3.2007

Репутация: 36
Всего: 46



я взял из javadoc GridLayout и заменил одну строку в методе layoutContainer(Container parent)  smile 
Код

import java.awt.*;

public class ForMichael implements LayoutManager, java.io.Serializable {
    int hgap;
    int vgap;
    int rows;
    int cols;

    public ForMichael() {
    this(1, 0, 0, 0);
    }

    public ForMichael(int rows, int cols) {
    this(rows, cols, 0, 0);
    }

    public ForMichael(int rows, int cols, int hgap, int vgap) {
    if ((rows == 0) && (cols == 0)) {
        throw new IllegalArgumentException("rows and cols cannot both be zero");
    }
    this.rows = rows;
    this.cols = cols;
    this.hgap = hgap;
    this.vgap = vgap;
    }

    public int getRows() {
    return rows;
    }

    public void setRows(int rows) {
    if ((rows == 0) && (this.cols == 0)) {
        throw new IllegalArgumentException("rows and cols cannot both be zero");
    }
    this.rows = rows;
    }

    public int getColumns() {
    return cols;
    }

    public void setColumns(int cols) {
    if ((cols == 0) && (this.rows == 0)) {
        throw new IllegalArgumentException("rows and cols cannot both be zero");
    }
    this.cols = cols;
    }

    public int getHgap() {
    return hgap;
    }
    
    public void setHgap(int hgap) {
    this.hgap = hgap;
    }
    
    public int getVgap() {
    return vgap;
    }
    
    public void setVgap(int vgap) {
    this.vgap = vgap;
    }

    public void addLayoutComponent(String name, Component comp) {
    }

    public void removeLayoutComponent(Component comp) {
    }

    public Dimension preferredLayoutSize(Container parent) {
      synchronized (parent.getTreeLock()) {
    Insets insets = parent.getInsets();
    int ncomponents = parent.getComponentCount();
    int nrows = rows;
    int ncols = cols;

    if (nrows > 0) {
        ncols = (ncomponents + nrows - 1) / nrows;
    } else {
        nrows = (ncomponents + ncols - 1) / ncols;
    }
    int w = 0;
    int h = 0;
    for (int i = 0 ; i < ncomponents ; i++) {
        Component comp = parent.getComponent(i);
        Dimension d = comp.getPreferredSize();
        if (w < d.width) {
        w = d.width;
        }
        if (h < d.height) {
        h = d.height;
        }
    }
    return new Dimension(insets.left + insets.right + ncols*w + (ncols-1)*hgap, 
                 insets.top + insets.bottom + nrows*h + (nrows-1)*vgap);
      }
    }

    public Dimension minimumLayoutSize(Container parent) {
      synchronized (parent.getTreeLock()) {
        Insets insets = parent.getInsets();
    int ncomponents = parent.getComponentCount();
    int nrows = rows;
    int ncols = cols;

    if (nrows > 0) {
        ncols = (ncomponents + nrows - 1) / nrows;
    } else {
        nrows = (ncomponents + ncols - 1) / ncols;
    }
    int w = 0;
    int h = 0;
    for (int i = 0 ; i < ncomponents ; i++) {
        Component comp = parent.getComponent(i);
        Dimension d = comp.getMinimumSize();
        if (w < d.width) {
        w = d.width;
        }
        if (h < d.height) {
        h = d.height;
        }
    }
    return new Dimension(insets.left + insets.right + ncols*w + (ncols-1)*hgap, 
                 insets.top + insets.bottom + nrows*h + (nrows-1)*vgap);
      }
    }

    public void layoutContainer(Container parent) {
      synchronized (parent.getTreeLock()) {
    Insets insets = parent.getInsets();
    int ncomponents = parent.getComponentCount();
    int nrows = rows;
    int ncols = cols;
    boolean ltr = parent.getComponentOrientation().isLeftToRight();

    if (ncomponents == 0) {
        return;
    }
    if (nrows > 0) {
        ncols = (ncomponents + nrows - 1) / nrows;
    } else {
        nrows = (ncomponents + ncols - 1) / ncols;
    }
    int w = parent.getWidth() - (insets.left + insets.right);
    int h = parent.getHeight() - (insets.top + insets.bottom);
    w = (w - (ncols - 1) * hgap) / ncols;

//    h = (h - (nrows - 1) * vgap) / nrows;
/////////////
h=w;   //////
/////////////

    if (ltr) {
        for (int c = 0, x = insets.left ; c < ncols ; c++, x += w + hgap) {
        for (int r = 0, y = insets.top ; r < nrows ; r++, y += h + vgap) {
            int i = r * ncols + c;
            if (i < ncomponents) {
            parent.getComponent(i).setBounds(x, y, w, h);
            }
        }
        }
    } else {
        for (int c = 0, x = parent.getWidth() - insets.right - w; c < ncols ; c++, x -= w + hgap) {
        for (int r = 0, y = insets.top ; r < nrows ; r++, y += h + vgap) {
            int i = r * ncols + c;
            if (i < ncomponents) {
            parent.getComponent(i).setBounds(x, y, w, h);
            }
        }
        }
    }
      }
    }
    
    public String toString() {
    return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + 
                        ",rows=" + rows + ",cols=" + cols + "]";
    }
}


PM MAIL   Вверх
_Michael
Дата 16.9.2007, 20:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 375
Регистрация: 23.6.2007
Где: з полонини

Репутация: 1
Всего: 6



dorogoyIV, я тоже свой SquareGridLayout сделал из java'всого GridLayout, сначала сделал так как у тебя, но так немного некрасиво , поскольку нету выравнивания по центру smile . Чтоб ето устранить, я ввел две дополнительные переменные dx и dy. 
Но вот сейчас немного протестировал и немного оно все равно не по центру. Например если установить 12 на 17 клеток ну или другой достаточно крупный размер то видно как компоненты размещены не по центру а немного левее на пару пикселов, так что на глаз заметно что не по центру. Ну ето наверное я уже придираюсь smile


--------------------
...не убивайся ни о чем - все временно,
хоть ночь темна но светлым днем беременна...

Саади
PM MAIL   Вверх
_Michael
Дата 16.9.2007, 22:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 375
Регистрация: 23.6.2007
Где: з полонини

Репутация: 1
Всего: 6



Только что опять наткнулся на новую проблему, я забыл учитывать в своем SquareGridLayout'е hgap и vgap. Но теперь уже исправил. Привожу здесь уже наверное окончательный вариант
Код

import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Insets;

public class SquareGridLayout extends GridLayout {

    /**
     * This field contains -4846453749417316063L.
     */
    private static final long serialVersionUID = -4846453749417316063L;
    
    private int rows;
    private int cols;
    private int hgap;
    private int vgap;

    public SquareGridLayout() {
        this(1, 0, 0, 0);
    }

    public SquareGridLayout(int rows, int cols) {
        this(rows, cols, 0, 0);
    }

    public SquareGridLayout(int rows, int cols, int hgap, int vgap) {
        if ((rows == 0) && (cols == 0)) {
            throw new IllegalArgumentException("rows and cols cannot both be zero");
        }
        this.rows = rows;
        this.cols = cols;
        this.hgap = hgap;
        this.vgap = vgap;
    }

    public void layoutContainer(Container parent) {
        Insets insets = parent.getInsets();
        int ncomponents = parent.getComponentCount();
        int nrows = rows;
        int ncols = cols;
        boolean ltr = parent.getComponentOrientation().isLeftToRight();

        if (ncomponents == 0) {
            return;
        }
        if (nrows > 0) {
            ncols = (ncomponents + nrows - 1) / nrows;
        } else {
            nrows = (ncomponents + ncols - 1) / ncols;
        }

        int w = parent.getWidth() - (insets.left + insets.right);
        int h = parent.getHeight() - (insets.top + insets.bottom);
        int dx = 0;
        int dy = 0;
        if ( (w - (cols-1)*hgap)*rows > (h - (rows-1)*vgap)*cols) {
         int a = (h - (nrows - 1) * vgap) / nrows;
         dx = (int)Math.round( (w + hgap - ( a + hgap)*cols) / 2);
         dy = (h + vgap - (a + vgap)*rows) / 2; 
         w = a;
         h = a;
        } else {
         int a = (w - (ncols - 1) * hgap) / ncols;
         dy = (int)Math.round( (h + vgap - ( a + vgap)*rows) / 2);
         dx = (w + hgap - (a + hgap)*cols) / 2; 
         h = a;
         w = a;
        }
        if (ltr) {
            for (int c = 0, x = insets.left + dx; c < ncols; c++, x += w + hgap) {
                for (int r = 0, y = insets.top + dy; r < nrows; r++, y += h    + vgap) {
                    int i = r * ncols + c;
                    if (i < ncomponents) {
                        parent.getComponent(i).setBounds(x, y, w, h);
                    }
                }
            }
        } else {
            for (int c = 0, x = parent.getWidth() - insets.right - w; c < ncols; c++, x -= w + hgap) {
                for (int r = 0, y = insets.top; r < nrows; r++, y += h + vgap) {
                    int i = r * ncols + c;
                    if (i < ncomponents) {
                        parent.getComponent(i).setBounds(x, y, w, h);
                    }
                }
            }
        }
    }

    public Dimension minimumLayoutSize(Container parent) {
        return super.minimumLayoutSize(parent);
    }

    public Dimension preferredLayoutSize(Container parent) {
        return super.preferredLayoutSize(parent);
    }
}


Добавлено через 1 минуту и 5 секунд
Работает отлично. Проверено мной smile


--------------------
...не убивайся ни о чем - все временно,
хоть ночь темна но светлым днем беременна...

Саади
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   jk1
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, jk1.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: GUI и Java FX приложения | Следующая тема »


 




[ Время генерации скрипта: 0.0573 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.