java - Canvas in JScrollPane only repaints when a scrollbar is at most extreme point -



i'm working on game project myself improve java skills , today i've hit problem cannot seem solve aid of internet. of problem has been solved last little bit still remains defiant!

i've got object extends canvas , creates map want display. i've added canvas jpanel, added viewport of jscrollpane (which added jframe of game). changelistener added jscrollpane's viewport, perform validate method on jframe , repaint method on viewport.
jframe has jmenubar, in menu structure there 'new game' option (among other not yet implemented jmenuitems) create new canvas object , replaces old 1 , validates (using validate methods) repaints jscrollpane.

the result when press new game jmenuitem, new map drawn out in scollpane. displays map (the canvas object) correctly, scollbars showing up. menu on top of canvas , scrollpane, correct.
when change position of scollbar (horizontal or vertical, using bar or buttons in bar) results in canvas object being translated across jframe. meaning overlap possibly scollbar, menubar (and drawn on opened menu) piece of canvas object out of view not being shown. when scrollbar hits it's extreme points (cannot go further), repaints , validates whole scene should. obviously, want when i'm nudging scrollbar or similar.

my question is: how can make work intended?
think need changelistener, can't seem find solution myself.

as noticed of guys ask source code, i've provided you:

 package otherfiles;

import java.awt.borderlayout; import java.awt.color; import java.awt.graphics; import java.awt.graphics2d; import java.awt.event.actionevent; import java.awt.event.actionlistener; import java.awt.geom.ellipse2d; import java.awt.geom.line2d; import java.awt.geom.rectangle2d; import java.util.arraylist;

import javax.swing.jcomponent; import javax.swing.jframe; import javax.swing.jmenu; import javax.swing.jmenubar; import javax.swing.jmenuitem; import javax.swing.jpanel; import javax.swing.jscrollpane;

public class problemdemonstrator { private static jscrollpane disparea = null; private static jpanel mappanel = null; private static jframe thisframe = null;

private static final int frame_width = 300; private static final int frame_heigth = 300; private static boolean mode = false; public static void main(string[] args){ jframe mainmenu = mymenuframe(); mainmenu.setdefaultcloseoperation(jframe.exit_on_close); mainmenu.setvisible(true); } public static jframe mymenuframe(){ thisframe = new jframe("problem demonstrator"); thisframe.setsize(frame_width, frame_heigth); thisframe.setlayout(new borderlayout()); //create menu bar , corresponding menu's. jmenubar menubar = new jmenubar(); thisframe.setjmenubar(menubar); menubar.add(createfilemenu(),borderlayout.north); //create scroll-able game display area disparea = new jscrollpane(); disparea.setsize(thisframe.getsize()); thisframe.getcontentpane().add(disparea, borderlayout.center); return thisframe; } private static jmenu createfilemenu() { jmenu menu = new jmenu("file"); menu.add(createfile_newgameitem()); //new game button return menu; } /** * button creation of new game. * @return jmenuitem starting new game. */ private static jmenuitem createfile_newgameitem() { jmenuitem item = new jmenuitem("new game"); class menuitemlistener implements actionlistener { @override public void actionperformed(actionevent arg0) { system.out.println("actionperformed - new game [jmenuitem]"); if(mappanel == null){ mappanel = creategamemap(mode); disparea.setviewportview(mappanel); }else{ disparea.getviewport().remove(mappanel); mappanel = creategamemap(mode); disparea.setviewportview(mappanel); } //'flip' mode if(mode){ mode = false; }else{ mode = true; } thisframe.pack(); thisframe.setsize(frame_width, frame_heigth); disparea.repaint(); thisframe.validate(); } } actionlistener l = new menuitemlistener(); item.addactionlistener(l); return item; } /** * creates displayable map has go in jscrollpane * @param mode variables able create 'random' maps. * @return displayable map, jpanel */ private static jpanel creategamemap(boolean mode){ /** * quick version of planets generate map. * class object, using class called planet * set parameters location, size , color in it's constructor. * x = x location on map (center of planet!) * y = y location on map (also center) * diam = diameter of planet */ @suppresswarnings("serial") class myplanetcomponent extends jcomponent{ private int x,y,diam; public myplanetcomponent(int x, int y, int diam){ this.x = x; this.y =y; this.diam = diam; } //paint circle on centre on (x,y) public void paintcomponent(graphics g){ graphics2d g2 = (graphics2d) g; g2.setcolor(color.blue); ellipse2d.double circle = new ellipse2d.double((x-diam/2), (y-diam/2), diam, diam ); g2.fill(circle); g2.setcolor(color.dark_gray); g2.draw(circle); //i want border around planet } public int getx(){ return this.x; } public int gety(){ return this.y; } } /** * quick way version of how create map display * intend use in game. it's collection of planets lines * between them, on black background. */ @suppresswarnings("serial") class mymap extends jpanel{ private boolean modeone; private int sizex, sizey; public mymap(boolean mode){ this.sizex = 500; this.sizey = 500; this.modeone = mode; //jpanel map = new jpanel(); this.setsize(this.sizex, this.sizey); } public int getsizex(){ return this.sizex; } public int getsizey(){ return this.sizey; } public void paintcomponent(graphics g){ graphics2d g2 = (graphics2d) g; //create black background plane //this.setbackground(color.black); //tried this, won't give bakcground int heightbg = this.getsizex(); int widthbg = this.getsizey(); rectangle2d.double spacebackground = new rectangle2d.double(0,0, heightbg, widthbg); g2.setcolor(color.black); g2.fill(spacebackground); //normally, import list somewhere else, result //is similar. arraylist<myplanetcomponent> planetslist = new arraylist<myplanetcomponent>(5); //need able generate @ least 2 different maps demonstrate //the effects of using new game button. list randomly //generated somewhere else, idea stays same. if(modeone){ planetslist.add(new myplanetcomponent(20,20,20)); planetslist.add(new myplanetcomponent(70,30,20)); planetslist.add(new myplanetcomponent(130,210,20)); planetslist.add(new myplanetcomponent(88,400,20)); planetslist.add(new myplanetcomponent(321,123,20)); }else{ planetslist.add(new myplanetcomponent(40,40,20)); planetslist.add(new myplanetcomponent(140,60,20)); planetslist.add(new myplanetcomponent(260,420,20)); planetslist.add(new myplanetcomponent(176,200,20)); planetslist.add(new myplanetcomponent(160,246,20)); } //for planets for(int i=0; i<planetslist.size()-1; i++){ //planet 1 coordinates myplanetcomponent p1 = planetslist.get(i); if(i == 0){ p1.paintcomponent(g2); //only draw planets once } //start coordinates of line int x1 = p1.getx(); int y1 = p1.gety(); //be smart, , don't things double! for(int j=i+1; j<planetslist.size(); j++){ myplanetcomponent p2 = planetslist.get(j);; if( == 0){ p2.paintcomponent(g2); //only draw planets once } //planet 2 coordinates, endpoint of line int x2 = p2.getx(); int y2 = p2.gety(); line2d.double traderoute = new line2d.double(x1, y1, x2, y2); g2.setcolor(color.green); g2.draw(traderoute); } } } } return new mymap(mode); }

}

your problem may due mixing awt , swing (heavy weight , light weight) components in same program, , shouldn't done, unless have definite need of , know you're doing. doubt need changelistener jscrollpanes should able handle sort of thing out of box. have tried having class extend jpanel or jcomponent instead of canvas?

also, when posting code, consider creating , posting sscce, small compilable runnable program can run, test, modify, , correct. if create , post type of code, you'll decent , complete solution quickly.

edit: created test program see effect canvas has on jscrollpanes, , it's thought -- canvas covers on scroll bars, , else. see compile , run code , resize jframe clicking , dragging. canvas blue , in jscrollpane on left while jpanel red , in jscrollpane on right.

import java.awt.*;  import javax.swing.*;  @suppresswarnings("serial") public class canvasinscrollpane extends jpanel {     private static final dimension canvas_size = new dimension(300, 300);     private static final dimension app_size = new dimension(500, 250);     canvas canvas = new canvas();     jpanel panel = new jpanel();      public canvasinscrollpane() {         canvas.setpreferredsize(canvas_size);         canvas.setbackground(color.blue);          panel.setpreferredsize(canvas_size);         panel.setbackground(color.red);          setpreferredsize(app_size);         setlayout(new gridlayout(1, 0, 5, 0));         add(new jscrollpane(canvas));         add(new jscrollpane(panel));     }      private static void createandshowui() {         jframe frame = new jframe("canvasinscrollpane");         frame.getcontentpane().add(new canvasinscrollpane());         frame.setdefaultcloseoperation(jframe.exit_on_close);         frame.pack();         frame.setlocationrelativeto(null);         frame.setvisible(true);     }      public static void main(string[] args) {         java.awt.eventqueue.invokelater(new runnable() {             public void run() {                 createandshowui();             }         });     } } 

Comments

Popular posts from this blog

javascript - Enclosure Memory Copies -

php - Replacing tags in braces, even nested tags, with regex -