Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Ich habe eine JScrollPane die den ViewPortView auf eine JTextArea hat.
Gibt es die Möglichkeit die Vertiale Scrollbar von der JScrollpane unabhänig von der JTextArea zu machen (So dass wenn ich an der Vertikalen ScrollBar scrolle sich nichts an der JTextArea verändert) ?
Ich schreib grad n kleines Tool zum logfiles analysieren. Und ich lad immer nur die Zeilen in die textarea die auch gebraucht werden. so erspar ich mir beim starten das komplette logfile durchzulesen. Gedacht hab ich mir wenn ich die vertikale scrollbar nehm kann ich anhand des values was der lineNumber der datei entspricht genau die zeilen einblenden. Dummerweise rutscht nach meinem "Scrollvorgang" die scrollbar nach unten und verändert wieder den maximalen index.
den code posten ^^ das könnte peinlich werden, aber gut
Also das da Alles in ne HashMap reingepackt wird will ich noch rausnehmen das war nur zum testen, aber könnte so funktionieren
Die Klasse ControlJFrame läd die Datei in eine HashMap und soll der Vertikalen Scrollbar der Klasse Gui die lineNumber als scrollwerte setzen.
Beim Scrollen soll dann anhand der value die zeilen aus der hashmap in die textarea übertragen werden.
Java:
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class Gui extends JFrame implements AdjustmentListener
{
/**
*
*/
private static final long serialVersionUID = 1L;
private JTextArea textArea = new JTextArea();
private ControlJFrame ctrJFrame = new ControlJFrame(this);
private JScrollPane scrollPane = new JScrollPane(textArea);
public Gui()
{
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(640,480);
this.add(scrollPane);
scrollPane.getVerticalScrollBar().addAdjustmentListener(this);
scrollPane.getViewport().remove(scrollPane.getVerticalScrollBar());
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
}
private void setTextToTextArea(String[] text)
{
textArea.setText("");
for(int i =0;i<text.length;i++)
{
if(text[i]!= null)
{
textArea.setText(textArea.getText()+System.getProperty("line.separator")+text[i]);
}
}
}
@Override
public void adjustmentValueChanged(AdjustmentEvent e)
{
setTextToTextArea(ctrJFrame.prepareTextForTextArea(e.getValue()));
}
public void setLineNumberOfFile(int lineNumber)
{
scrollPane.getVerticalScrollBar().setMaximum(lineNumber);
}
}
Und hier die andere Klasse
Java:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.HashMap;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JScrollBar;
public class ControlJFrame extends JFrame implements ActionListener
{
/**
*
*/
private static final long serialVersionUID = 1L;
private Gui gui;
private JButton loadLogFileJButton = new JButton("Load File");
private File logFile;
private HashMap<Integer, String> lineHashMap = new HashMap<Integer, String>();
private HashMap<Integer, Boolean> errorHashMap = new HashMap<Integer, Boolean>();
public ControlJFrame(Gui gui)
{
this.gui=gui;
this.setSize(300,300);
this.setVisible(true);
this.setLayout(null);
loadLogFileJButton.setSize(180,20);
loadLogFileJButton.addActionListener(this);
this.add(loadLogFileJButton);
}
private void parseLogFileToHashMap()
{
try
{
BufferedReader br = new BufferedReader(new FileReader(logFile));
String line;
int lineCounter = 0;
while ((line = br.readLine()) != null)
{
errorHashMap.put(lineCounter, line.contains("Excpetion"));
lineHashMap.put(lineCounter, line);
lineCounter++;
}
gui.setLineNumberOfFile(lineCounter);
} catch (Exception e)
{
e.printStackTrace();
}
System.out.println(lineHashMap.size());
}
@Override
public void actionPerformed(ActionEvent e)
{
if(e.getSource().equals(loadLogFileJButton))
{
JFileChooser fileChooser = new JFileChooser();
if(fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION)
{
logFile = fileChooser.getSelectedFile();
parseLogFileToHashMap();
}
}
}
public String[] prepareTextForTextArea(int lineNumber)
{
String[] text = new String[50];
for (int i =0;i< 50;i++)
{
text[i] = lineHashMap.get(lineNumber+i);
}
return text;
}
}
Gut oder mal anderst gefragt, wie programmiert man einen texteditor der 10 gig große logfiles öffnen kann ohne 10 minuten zu laden
Meine idee war dass ich später wenn das mal so klappt nur das nachlade was ich auch brauch, also den schritt mit der hashmap möchte ich später wieder rausnehmen.
Ich würde einen anderen Weg wählen: Eine eigene Implementation von AbstractDocument.Content die stets nur rund um die letzte Anfrage Daten vorhält. Diesen Content kann man dann an ein PlainDocument übergeben. Das ist zwar bei weitem nicht trivial, aber auch nicht komplizierter als das Scrollen vernünftig zu implementieren.
Um nur Deine Frage zu beantworten: JViewport ableiten und so implementieren / überschreiben:
Java:
final Point virtualViewPosition = new Point();
@Override
public Point getViewPosition() {
return virtualViewPosition;
}
@Override
public void setViewPosition(Point p) {
virtualViewPosition.setLocation(p);
final Point p2 = super.getViewPosition();
p2.x = p.x;
super.setViewPosition(p2);
}
[Edit] Hab's getestet und das Beispiel oben grad nochmal geändert. Nicht wundern.