我想編寫一個自定義的JPanel,它遵循包含JPanel的layoutmanager(我正在使用gridbag)。我的自定義JPanel在這裏粘貼時間有點過長,但需要覆蓋所有方法的清單才能使其工作。編寫將遵循LayoutManager規範的自定義JPanel
這裏是我的自定義JPanel的摘錄:
public class GridPanel extends JPanel implements MouseMotionListener, MouseListener{
private Rectangle offdutyRect, sbRect, driveRect, onRect;
private int delta = 60;
private int[][] gridArray;
int draggedStartX = -1;
int draggedStartY = -1;
private int dutyStatusSpacing = 60;
private int totalSpacing = 100;
public GridPanel(){
this.setSize(new Dimension(800, 100));
this.addMouseMotionListener((MouseMotionListener) this);
this.addMouseListener(this);
int gridArrayColumns = 24*60/delta;
gridArray = new int[4][gridArrayColumns];
int r = 0;
int rHeight = this.getHeight()/4;
offdutyRect = new Rectangle(this.getX() + dutyStatusSpacing, this.getY() + r*rHeight, this.getWidth() - totalSpacing, rHeight);
r++;
sbRect = new Rectangle(this.getX() + dutyStatusSpacing, this.getY() + r*rHeight, this.getWidth() - totalSpacing, rHeight);
r++;
driveRect = new Rectangle(this.getX() + dutyStatusSpacing, this.getY() + r*rHeight, this.getWidth() - totalSpacing, rHeight);
r++;
onRect = new Rectangle(this.getX() + dutyStatusSpacing, this.getY() + r*rHeight, this.getWidth() - totalSpacing, rHeight);
Rectangle rect = null;
for(r = 0; r < gridArray.length; r++){
if(r == 0){
rect = offdutyRect;
}else if(r == 1){
rect = sbRect;
}else if(r == 2){
rect = driveRect;
}else if(r == 3){
rect = onRect;
}
//I haven't actually derived any of these things, just my best guesses.
int len = gridArray[r].length;
int width = (int) (rect.getWidth()/len);
rect.setSize((int)(width*len), (int) rect.getHeight());
}
}
public void paintComponent(Graphics g){
g.clearRect(this.getX(), this.getY(), this.getWidth(), this.getHeight());
//the center black bar for duty status "placeholders"
g.setColor(Color.black);
g.drawRect(getX(), getY(), getWidth() - 1, getHeight() - 1);
g.drawRect((int)offdutyRect.getX(), (int)offdutyRect.getY() + (int)offdutyRect.getHeight()/2, (int)offdutyRect.getWidth(), 1);
g.drawRect((int)sbRect.getX(), (int)sbRect.getY() + (int)sbRect.getHeight()/2, (int)sbRect.getWidth(), 1);
g.drawRect((int)driveRect.getX(), (int)driveRect.getY() + (int)driveRect.getHeight()/2, (int)driveRect.getWidth(), 1);
g.drawRect((int)onRect.getX(), (int)onRect.getY() + (int)onRect.getHeight()/2, (int)onRect.getWidth(), 1);
g.setColor(Color.pink);
g.drawRect((int)offdutyRect.getX(), (int)offdutyRect.getY(), (int)offdutyRect.getWidth(), (int)offdutyRect.getHeight());
g.drawRect((int)sbRect.getX(), (int)sbRect.getY(), (int)sbRect.getWidth(), (int)sbRect.getHeight());
g.drawRect((int)driveRect.getX(), (int)driveRect.getY(), (int)driveRect.getWidth(), (int)driveRect.getHeight());
g.drawRect((int)onRect.getX(), (int)onRect.getY(), (int)onRect.getWidth(), (int)onRect.getHeight());
//draw the array
g.setColor(Color.green);
Rectangle rect = null;
for(int r = 0; r < gridArray.length; r++){
if(r == 0){
rect = offdutyRect;
}else if(r == 1){
rect = sbRect;
}else if(r == 2){
rect = driveRect;
}else if(r == 3){
rect = onRect;
}
//I haven't actually derived any of these things, just my best guesses.
int len = gridArray[r].length;
int width = (int) (rect.getWidth()/len);
int height = (int) rect.getHeight() - 2;
for(int c = 0; c < gridArray[r].length; c++){
if(gridArray[r][c] == 1){
int x = (int) (rect.getX() + width*c);
int y = (int) rect.getY() + 2;
g.fillRect(x, y, width, height);
}
}
}
}
//implement setSize
public void setSize(Dimension d){
if(gridArray == null){
int gridArrayColumns = 24*60/delta;
gridArray = new int[4][gridArrayColumns];
}
int r = 0;
int rHeight = this.getHeight()/4;
offdutyRect = new Rectangle(this.getX() + dutyStatusSpacing, this.getY() + r*rHeight, (int)d.getWidth() - totalSpacing, rHeight);
r++;
sbRect = new Rectangle(this.getX() + dutyStatusSpacing, this.getY() + r*rHeight, (int)d.getWidth() - totalSpacing, rHeight);
r++;
driveRect = new Rectangle(this.getX() + dutyStatusSpacing, this.getY() + r*rHeight, (int)d.getWidth() - totalSpacing, rHeight);
r++;
onRect = new Rectangle(this.getX() + dutyStatusSpacing, this.getY() + r*rHeight, (int)d.getWidth() - totalSpacing, rHeight);
Rectangle rect = null;
for(r = 0; r < gridArray.length; r++){
if(r == 0){
rect = offdutyRect;
}else if(r == 1){
rect = sbRect;
}else if(r == 2){
rect = driveRect;
}else if(r == 3){
rect = onRect;
}
//I haven't actually derived any of these things, just my best guesses.
int len = gridArray[r].length;
int width = (int) (rect.getWidth()/len);
rect.setSize((int)(width*len), (int) rect.getHeight());
}
}
}
這裏是相對較短的定製容器,我的自定義類的多個實例將被添加:
public class GridContainer extends JPanel implements ActionListener{
List<GridPanel> panels = new ArrayList<GridPanel>();
public GridContainer(){
GridBagLayout gb = new GridBagLayout();
this.setLayout(gb);
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
c.weightx = .5;
c.weighty = .5;
c.fill = GridBagConstraints.HORIZONTAL;
BufferedImage img = null;
try {
img = ImageIO.read(this.getClass().getResource("/res/add.png"));
} catch (IOException e) { }
JButton addButton = new JButton();
addButton.setIcon(new ImageIcon(img));
addButton.addActionListener(this);
this.add(addButton, c);
}
public void actionPerformed(ActionEvent e) {
System.out.println("action performed" + panels.size());
this.setLayout(new GridBagLayout());
removeAll();
repaint();
panels.add(new GridPanel());
int r = 0;
GridBagConstraints c = new GridBagConstraints();
for(int i = 0; i < panels.size(); i++){
JLabel label = new JLabel("day " + i);
c = new GridBagConstraints();
c.gridx = 0;
c.gridy = r;
c.weightx = 1;
c.weighty = 1;
this.add(label, c);
r++;
c = new GridBagConstraints();
c.gridx = 0;
c.gridy = r;
c.weightx = 1;
c.weighty = 1;
c.fill = GridBagConstraints.HORIZONTAL;
this.add(panels.get(i), c);
r++;
}
c = new GridBagConstraints();
c.gridx = 0;
c.gridy = r;
c.weightx = 1;
c.weighty = 1;
c.fill = GridBagConstraints.HORIZONTAL;
BufferedImage img = null;
try {
img = ImageIO.read(this.getClass().getResource("/res/add.png"));
} catch (IOException ex) { }
JButton addButton = new JButton();
addButton.setIcon(new ImageIcon(img));
addButton.addActionListener(this);
this.add(addButton, c);
repaint();
}
}
不要覺得有義務調試這段代碼,只是在某些情況下我在哪裏。
代替'setSize',你可以1-使用佈局管理器; 2-覆蓋'doLayout' ...你也沒有調用'super.setSize' – MadProgrammer
在自定義JPanel中使用佈局管理器? – ceptno
我與你的代碼有問題,你的網格窗格有沒有首選的大小 – MadProgrammer