Swing Horizontales Scrollen mit Shift-Mausrad

Petra19

Mitglied
Hallo zusammen,

ich bin immer noch mit den Scrollbalken beschäftigt.

Ich möchte mit der Shift-Mausrad-Kombination horizontal scrollen. Hierzu habe ich zwei Ansätze ausprobiert. Einmal mit
Java:
else if(evt.isShiftDown()){
  location.x+=UNIT_INCREMENT*evt.getWheelRotation();
  if (location.x<0)  location.x=0;
  //Obere Grenze fehlt
  scrollPane.getHorizontalScrollBar().setValue(location.x);
}
In diesem Fall wird zuerst nach oben bzw. nach unten gescrollt. Ich möchte aber mit Shift-Mausrad nur nach rechts bzw. links scrollen.

Mein zweiter Ansatz stellt mich ebenfalls nicht zufrieden, da sich das Bild beim Scrollen kurz nach oben bewegt. Ich vermute, dass ich mit dem Mausrad vertikal scrolle und anschl. die Position mit setViewPosition() wieder verändere.
Java:
else if(evt.isShiftDown()){
  location.x+=UNIT_INCREMENT*evt.getWheelRotation();
  if (location.x<0)  location.x=0;
  //Obere Grenze fehlt
  scrollPane.getViewport().setViewPosition(location);
  }
  else{
  location.y+=UNIT_INCREMENT;
  if (location.y<0) location.y=0;
  //Obere Grenze fehlt
  }

Leider weiß ich nicht, wie ich das ändern kann.

Weiter weiß ich nicht, wie ich location.x (location.y) nach oben begrenzen kann. Mit getWidth(), oder getMaximum() komme ich nicht weiter, da ich nicht die Breite des Scrollbalkens, der sich je nach Größe von MyPanel ändert. Auch hier könnte ich einen Hinweis brauchen.

Vielen Dank für eure Hilfe!


Hier nun mein Quellcode:
Java:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.geom.Ellipse2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class ScrollAndZoomExample {
  public static void main(String[] args) {
  final int UNIT_INCREMENT=25;
  JFrame f = new JFrame();
  f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  DrawingPanel myPanel=new DrawingPanel();
   
  Point location=new Point(0,0);
   
  JScrollPane scrollPane=new JScrollPane();
  scrollPane.getViewport().setView(myPanel);
  scrollPane.getHorizontalScrollBar().setUnitIncrement(UNIT_INCREMENT);
  scrollPane.getVerticalScrollBar().setUnitIncrement(UNIT_INCREMENT);
  scrollPane.addMouseWheelListener(new MouseWheelListener() {
   @Override
   public void mouseWheelMoved(MouseWheelEvent evt) {
    if (evt.isControlDown()) {
      myPanel.setScale(evt.getWheelRotation());
    }
    else if(evt.isShiftDown()){
      location.x+=UNIT_INCREMENT*evt.getWheelRotation();
      if (location.x<0)  location.x=0;
      //Obere Grenze fehlt
      scrollPane.setAutoscrolls(false);
      scrollPane.getHorizontalScrollBar().setValue(location.x);
    }/*
      scrollPane.getViewport().setViewPosition(location);
    }
    else{
      location.y+=UNIT_INCREMENT;
      if (location.y<0) location.y=0;
      //Obere Grenze fehlt
    }*/
   }
  });
  f.getContentPane().setLayout(new BorderLayout());
  f.getContentPane().add(scrollPane,BorderLayout.CENTER);
  f.setSize(400, 400);
  f.setLocation(200,200);
  f.setVisible(true);
  }
}


class DrawingPanel extends JPanel{
  int scale;
  int width=100;
  int height=100;
   
  public DrawingPanel(){
  scale= 1;
  setPreferredSize(new Dimension(100,100));
   
  }
  protected void paintComponent(Graphics g) {
  super.paintComponent(g);
  Graphics2D g2 = (Graphics2D)g;
  g2.scale(scale,scale);
  g2.draw(new Ellipse2D.Double(10, 10, 20, 20));
  g2.draw(new Ellipse2D.Double(10, 10, 40, 40));
  g2.draw(new Ellipse2D.Double(10, 10, 60, 60));
  g2.draw(new Rectangle(0,0,width,height));
 }
   
  public void setScale(int s){
  scale=scale-s;
  if (scale<1) scale=1;
  else if (scale>15) scale=15;
  setPreferredSize(new Dimension(width*scale, height*scale));
  revalidate();
  repaint();
  }
}
 
Ohne das jetzt feoß nachgesehen zu haben. Gibt es keine Möglichkeit von JScrollPane anzuleiten und die entsprechenden Methode zu überschreiben die die Scrollen oder das Scrolling steuern ?

Gruß

Claus
 
Hallo zusammen,

'habe noch weiter im Forum gestöbert und bin auf den folgenden Artikel gestoßen: http://www.java-forum.org/thema/scrollen-per-mousedragged-jscrollpane.72156/

Dieser lieferte mir die Lösung für meine beiden Probleme.
1.) Ausschalten des Scrollens mit Mausrad (scrollPane.setWheelScrollingEnabled(false)😉
2.) Mit der Methode getViewPort.getExtentSize() erhalte ich die notwendigen Werte zur Begrenzung des Maximums für die Variablen location.x bzw. location.y

Vielen Dank euch Allen.

Hier nun der endgültige Quellcode:
Java:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.geom.Ellipse2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JViewport;

public class ScrollAndZoomExample {
  public static void main(String[] args) {
  final int UNIT_INCREMENT=25;
  JFrame f = new JFrame();
  f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  DrawingPanel myPanel=new DrawingPanel();
   
  Point location=new Point(0,0);
   
  JScrollPane scrollPane=new JScrollPane();
  scrollPane.getViewport().setView(myPanel);
  scrollPane.getHorizontalScrollBar().setUnitIncrement(UNIT_INCREMENT);
  scrollPane.getVerticalScrollBar().setUnitIncrement(UNIT_INCREMENT);
   
  scrollPane.setWheelScrollingEnabled(false);
   
  scrollPane.addMouseWheelListener(new MouseWheelListener() {
    @Override
    public void mouseWheelMoved(MouseWheelEvent evt) {
    JViewport v = scrollPane.getViewport();
    Dimension extentSize = v.getExtentSize();
    Dimension  viewSize= v.getView().getSize();
    if (evt.isControlDown()) {
      myPanel.setScale(evt.getWheelRotation());
    }
    else if(evt.isShiftDown()){
      location.x+=UNIT_INCREMENT*evt.getWheelRotation();
      if (location.x<0)  location.x=0;
      else if(location.x>viewSize.width-extentSize.width) location.x=viewSize.width-extentSize.width;
   
      scrollPane.getHorizontalScrollBar().setValue(location.x);
    }
    else{
      location.y+=UNIT_INCREMENT*evt.getWheelRotation();
      if (location.y<0) location.y=0;
      else if(location.y>viewSize.height-extentSize.height) location.y=viewSize.height-extentSize.height;
      scrollPane.getVerticalScrollBar().setValue(location.y);
    }
  }
  });
  f.getContentPane().setLayout(new BorderLayout());
  f.getContentPane().add(scrollPane,BorderLayout.CENTER);
  f.setSize(400, 400);
  f.setLocation(200,200);
  f.setVisible(true);
  }
}


class DrawingPanel extends JPanel{
  int scale;
  int width=100;
  int height=100;
   
  public DrawingPanel(){
  scale= 1;
  setPreferredSize(new Dimension(100,100));
   
  }
  protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D)g;
    g2.scale(scale,scale);
    g2.draw(new Ellipse2D.Double(10, 10, 20, 20));
    g2.draw(new Ellipse2D.Double(10, 10, 40, 40));
    g2.draw(new Ellipse2D.Double(10, 10, 60, 60));
    g2.draw(new Rectangle(0,0,width,height));
  }
   
  public void setScale(int s){
    scale=scale-s;
    if (scale<1) scale=1;
    else if (scale>15) scale=15;
    setPreferredSize(new Dimension(width*scale, height*scale));
    revalidate();
    repaint();
  }
}
 

Zurück
Oben