java - JPanel with JComponents inside a JScrollPane and custom LayoutManager -


i have written subclass of jcomponent draws in paintcomponent method. in constructor set bounds setbounds. works fine. added subclass jpanel. jpanel inside jscrollpane. jpanel class subclassing jpanel , implementing mouseinputlistener , keylistener. whenever user clicks in jpanel bounds of each jcomponent check against mouse point. if matched focus set jcomponent. if focus @ jcomponent , user drags mouse jcomponent moved inside jpanel. want achive whenever position of jcomponent inside jpanel changes , gets out of viewport of jscrollpane scrollbars gets visible , jpanel gets resized user can scroll outside of viewable area. achive have written custom layoutmanager not layout jcomponents in way absolute position. whenever move jcomponent inside jpanel , outside of viewable area scrollbars not updated. how can achive this?

here class subclassig jcomponent:

public abstract class gate extends jcomponent {  /**  *   */ private static final long serialversionuid = 1l;  public gate() {     super();     setbounds(new rectangle(0, 0, 100, 100));     setborder(borderfactory.createlineborder(color.black));     setfocusable(true);     setopaque(false);     setbackground(color.white); }  @override protected void paintcomponent(graphics g) {     super.paintcomponent(g);     if(hasfocus()) {         setborder(borderfactory.createlineborder(color.green));     } else {         setborder(borderfactory.createlineborder(color.black));     }     graphics g2 = g.create();     g2.setcolor(getbackground());     g2.fillrect(0, 0, getwidth(), getheight());     g2.dispose(); } } 

here class subclassing jpanel:

public class gatespanel extends jpanel implements mouseinputlistener, keylistener {  /**  *   */ private static final long serialversionuid = 1l;  public gatespanel() {     super();     setlayout(new gatelayout());     addmouselistener(this);     addmousemotionlistener(this);     addkeylistener(this);     setfocusable(true); }  @override public void mouseclicked(mouseevent e) {     if(e.getbutton() == mouseevent.button1) {         for(int = 0; < getcomponentcount(); i++) {             component c = getcomponent(i);             if(c instanceof jcomponent) {                 jcomponent j = (jcomponent)c;                 if(j.getbounds().contains(e.getpoint())) {                     if(j.hasfocus()) {                         grabfocus();                     } else {                         j.grabfocus();                     }                 }             }         }     } }  @override public void mouseentered(mouseevent e) {  }  @override public void mouseexited(mouseevent e) {  }  @override public void mousepressed(mouseevent e) {  }  @override public void mousereleased(mouseevent e) {  }  @override public void mousedragged(mouseevent e) {  }  @override public void mousemoved(mouseevent e) {     for(int = 0; < getcomponentcount(); i++) {         component c = getcomponent(i);         if(c.hasfocus()) {             c.setlocation(e.getpoint());         }     } }  @override public void keypressed(keyevent e) {  }  @override public void keyreleased(keyevent e) {  }  @override public void keytyped(keyevent e) {  } } 

and here class implementing layoutmanager:

public class gatelayout implements layoutmanager {  private int minwidth; private int minheight; private int preferedwidth; private int preferedheight;  public gatelayout() {     minwidth = 0;     minheight = 0;     preferedwidth = 0;     preferedheight = 0; }  @override public void addlayoutcomponent(string name, component component) {  }  @override public void layoutcontainer(container parent) {      setsize(parent); }  private void setsize(container parent) {     minwidth = 0;     minheight = 0;     preferedwidth = 0;     preferedheight = 0;     for(int = 0; < parent.getcomponentcount(); i++) {         component c = parent.getcomponent(i);         dimension d = c.getpreferredsize();         minwidth = math.max(d.width, minwidth);         minheight = math.max(d.height, minheight);         preferedwidth += d.width;         preferedheight += d.height;     } }  @override public dimension minimumlayoutsize(container parent) {     setsize(parent);     insets insets = parent.getinsets();     return new dimension(minwidth + insets.left + insets.right,                         minheight + insets.top + insets.bottom); }  @override public dimension preferredlayoutsize(container parent) {     setsize(parent);     insets insets = parent.getinsets();     return new dimension(preferedwidth + insets.left + insets.right,                          preferedheight + insets.top + insets.bottom); }  @override public void removelayoutcomponent(component component) {  }  } 

in jframe subclass called gatesframe call following code:

gatespanel = new gatespanel(); jscrollpane scrollpane = new jscrollpane(gatespanel); scrollpane.sethorizontalscrollbarpolicy(jscrollpane.horizontal_scrollbar_always); scrollpane.setverticalscrollbarpolicy(jscrollpane.vertical_scrollbar_always); scrollpane.setautoscrolls(true); setcontentpane(scrollpane); 

after add gate subclass called gateand gatespanel:

gatespanel.add(new gateand()); 

so doing wrong scrollbars gets not updated when user moves component inside panel surrounded scroll pane? welcome.

greez,

maxpa1n87

to achive have written custom layoutmanager not layout jcomponents in way absolute position. whenever move jcomponent inside jpanel , outside of viewable area scrollbars not updated.

maybe layout manager not setting preferred size correctly. scrollbars appear automatically when preferred size greater size of scrollpane.

you need make sure when finished dragging component invoke revalidate() on panel layout manager invoked.

check out drag layout designed purpose.

here simple example:

import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.border.*;  public class draglayouttest {     public static void main( string[] args )     {         draglistener drag = new draglistener();          draglayout dl = new draglayout();         dl.setusepreferredsize(false);          jpanel panel = new jpanel( dl );         panel.setborder( new matteborder(10, 10, 10, 10, color.yellow) );          createlabel(drag, panel, "north", 150, 0);         createlabel(drag, panel, "west", 0, 100);         createlabel(drag, panel, "east", 300, 100);         createlabel(drag, panel, "south", 150, 200);         createlabel(drag, panel, "center", 150, 100);          jframe.setdefaultlookandfeeldecorated(true);         jframe frame = new jframe( "drag layout" );         frame.setdefaultcloseoperation(jframe.exit_on_close);         frame.add( new jscrollpane(panel) );         frame.pack();         frame.setlocationrelativeto( null );         frame.setvisible( true );     }      public static void createlabel(mouseinputadapter drag, jpanel panel, string text, int x, int y)     {         jlabel label = new jlabel( text );         label.setopaque(true);         label.setbackground( color.orange );         label.setlocation(x, y);         panel.add( label );         label.addmouselistener( drag );         label.addmousemotionlistener( drag );     }      static class draglistener extends mouseinputadapter     {         point location;         mouseevent pressed;          public void mousepressed(mouseevent me)         {             pressed = me;         }          public void mousedragged(mouseevent me)         {             component component = me.getcomponent();             location = component.getlocation(location);             int x = location.x - pressed.getx() + me.getx();             int y = location.y - pressed.gety() + me.gety();             component.setlocation(x, y);             ((jcomonent)component.getparent()).revalidate();          }     } } 

Comments

Popular posts from this blog

matlab - error with cyclic autocorrelation function -

django - (fields.E300) Field defines a relation with model 'AbstractEmailUser' which is either not installed, or is abstract -

c# - What is a good .Net RefEdit control to use with ExcelDna? -