Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: GUI и Java FX приложения > Добавление компонентов в JTextPane


Автор: JulT 28.9.2006, 16:21
Вообще есть JTextPane в нем текст,выделяем слово в JTextPane ,при нажатии правой клавиши я сделала выпадающее меню,когда жмем на один из пунктов меню у меня заместь выделенного слова в JTextPane вставляется кнопка с названием этого слова.Таких кнопок получается несколько,на каждую из них я повесила обработчик события.Также,на каждую из этих кнопок я повесила другое выпадающее меню,в котором находится пункт,нажимая на который мне нужно чтобы кнопка удалялась,а на ее место вставлялось слово которое было до этого.Вопрос в следующем:1)как удалить нужную мне кнопку
2) нужно ли хранить все кнопки в отдельном массиве,для того чтобы с каждой в отделности можно было работать
3) где фиксировать координаты кнопки,потому что если не фиксировать,то выпадающая менюшка которая относится к кнопкам всегда вылазит только на последней созданной кнопке
Надеюсь поняли меня,ХЭЛП МИ ПЛИЗ

Автор: LSD 28.9.2006, 16:31
1. Название темы должно отражать ее суть!

2. 
Цитата(JulT @  28.9.2006,  17:21 Найти цитируемый пост)
1)как удалить нужную мне кнопку

textPane.remove(button)

3. 
Цитата(JulT @  28.9.2006,  17:21 Найти цитируемый пост)
2) нужно ли хранить все кнопки в отдельном массиве,для того чтобы с каждой в отделности можно было работать

Как-то их хранить завсисит от того как спроектировано приложение, вообщем это вполне приемлемый способ. Только лучше использовать не массив, а какая нибудь коллекцию, например ArrayList.

4. 
Цитата(JulT @  28.9.2006,  17:21 Найти цитируемый пост)
3) где фиксировать координаты кнопки,потому что если не фиксировать,то выпадающая менюшка которая относится к кнопкам всегда вылазит только на последней созданной кнопке

Код
Point location = button.getLocation();

Это координаты относительно JTextPane, с помощью класса SwingUtilities их можно сконвертировать в координаты относительно экрана или другого компонента.

Автор: JulT 28.9.2006, 16:52
не удаляет у меня он кнопку,делаю так:
Код

jTextPane2.addMouseListener(new MouseAdapter(){
      public void mouseClicked(MouseEvent e){
                pop=new JPopupMenu();
          if (e.getButton()==MouseEvent.BUTTON3) {
            Point p = e.getPoint();
                    JMenuItem menuItem4 = new JMenuItem("Сделать ключевым словом",new ImageIcon(CreateNewTest.class.getResource("img/l_rename.gif")));
                    pop.add(menuItem4).addActionListener(new ActionListener(){
                             public void actionPerformed(ActionEvent e){
                                    start=jTextPane2.getSelectionStart();
                                    end=jTextPane2.getSelectionEnd();
  button=new JButton(jTextPane2.getSelectedText().trim());
                button.setIcon(new ImageIcon(CreateNewTest.class.getResource("img/l_rename.gif")));
                button.setSize(jTextPane2.getSelectedText().trim().length(),8);
   //  а теперь тут создаю выпадающее меню,для только что созданной кнопки
   button.addMouseListener(new MouseAdapter(){
                  public void mouseClicked(MouseEvent q){
                     //System.out.println("1!!!!!!");
                       pop2=new JPopupMenu();
       if (q.getButton()==MouseEvent.BUTTON3) {
           p3 = q.getPoint();
           JMenuItem menuItem11 = new JMenuItem("Убрать ключевое слово",new ImageIcon(CreateNewTest.class.getResource("img/l_rename.gif")));
           pop2.add(menuItem11).addActionListener(new ActionListener(){
                 public void actionPerformed(ActionEvent s){
                        removeButton(button);
     }
                      });
                  Point location = button.getLocation();
                  pop2.show(button, location.x, location.y);
              }

                  }
                });


    где-то там метод для удаления
  public void  removeButton(JButton b){
        jTextPane2.remove(b);
        jTextPane2.updateUI();
    }

ничего не удаляет,менюшка вылазит не понятно где smile 
                             

Автор: LSD 28.9.2006, 17:06
Меню отображается не там где надо потому что когда ты пишешь pop2.show(button, location.x, location.y) - то x, y должны быть смещением относительно button, т.е. что-то типа такого:
Код
popupMenu.show(button, button.getWidth() / 2, button.getHeight() / 2);


А насчет того почему кнопка не удаляется сложно сказать, по идее должна, попробуй модифицировать код так:
Код
public void actionPerformed(ActionEvent s)
{
  System.out.println("Call remove button: " + button.getText());
  removeButton(button);
}

Автор: JulT 28.9.2006, 17:25
Ничего не помагает,есть 2 кнопки,одна называется Кнопка1 ее я создала первой, вторая наз Кнопка2, 
в результате менюшка вылазит только на Кнопке2 и соответственно вывод в консоль постоянно такой:  Call remove button: Кнопка2 smile  smile 

Автор: LSD 28.9.2006, 17:33
Вот и источник проблемы: ты неправильно определяешь с какой кнопкой работать. Попробуй получать нужную кнопку так:
Код
button.addMouseListener(new MouseAdapter()
{
  public void mouseClicked(MouseEvent q)
  {
    final JButton currentButton = (JButton) q.getSource();
    pop2 = new JPopupMenu();
    if(q.getButton() == MouseEvent.BUTTON3)
    {
      p3 = q.getPoint();
      JMenuItem menuItem11 = new JMenuItem("Убрать ключевое слово", new ImageIcon(CreateNewTest.class.getResource("img/l_rename.gif")));
      pop2.add(menuItem11).addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent s)
        {
          removeButton(currentButton);
        }
      });
      pop2.show(currentButton, 1, 1);
    }
  }
}

Автор: JulT 28.9.2006, 18:01
Не удаляется,но в консоли пишет уже разные названия кнопок

Автор: LSD 28.9.2006, 21:04
Теперь модифицируй метод removeButton():
Код
public void removeButton(JButton b)
{
  Component[] components = jTextPane2.getComponents();
  for(Component component : components)
  {
    if(component == b)
    {
      System.out.println("jTextPane2 contains button " + b.getText());
      break;
    }
  }
  jTextPane2.remove(b);
}

Автор: JulT 29.9.2006, 11:08
А он мне подчеркивает 
Код

Component component : components 
и говорит что ошибка:
Код

"CreateNewTest.java": Error #: 206 : malformed expression at line 515, column 17

первый раз такую запись for вижу

Автор: powerOn 29.9.2006, 11:11
Цитата(JulT @  29.9.2006,  12:08 Найти цитируемый пост)
А он мне подчеркивает код :Component component : components .... и говорит что ошибка:


А какая у вас версия Java? Данный код будет работать в Java версии не ниже 1.5...

Автор: LSD 29.9.2006, 11:13
Замени:
Код
for(Component component : components)

на
Код
for(int i = 0; i < components.length; i++)


Ты используешь не JDK 1.5?

Автор: JulT 29.9.2006, 11:23
я использую JDK 1.4
Написала так как вы сказали :
Код

  public void removeButton(JButton b){
  Component[] components = jTextPane2.getComponents();
 for(int i = 0; i < components.length; i++){
   Component component= components[i];
    if(component == b){
      System.out.println("jTextPane2 contains button " + b.getText());
      break;
    }
  }
  jTextPane2.remove(b);
}

но все равно не удаляет smile

Добавлено @ 11:27 
чуть не забыла,в консоли ничего не отрабатвается  
Код

System.out.println("jTextPane2 contains button " + b.getText());

Автор: LSD 29.9.2006, 11:30
Значит кнопка не добавлена в jTextPane2. Тут уже надо анализировать весь код, особенно тот место где ты добавляешь кнопку в jTextPane2.

Автор: JulT 29.9.2006, 11:38
добавляю сто процентов,ведь я ее вижу своими глазами, при нажатии на нее у меня другое окошко вылазит,Боже мой что же делать.Вставляю я вот так вот: 
Код

button=new JButton(jTextPane2.getSelectedText().trim());
                button.setIcon(new ImageIcon(CreateNewTest.class.getResource("img/l_rename.gif")));
                button.setSize(jTextPane2.getSelectedText().trim().length(),8);
                jTextPane2.insertComponent(button);

помогите,не бросайте меня

Автор: LSD 29.9.2006, 12:07
Попробуй сделать так:
Код
public static void main(String[] args) throws Exception
{
  JButton button1 = new JButton("My button 1");
  JButton button2 = new JButton("My button 2");
  JTextPane textPane = new JTextPane();
  textPane.setText("Abcd  efg hij klmnop qrst uvw xyz");
  textPane.setCaretPosition(5);
  textPane.insertComponent(button1);
  textPane.setCaretPosition(5);
  textPane.insertComponent(button2);

  JFrame frame = new JFrame();
  frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
  frame.getContentPane().add(textPane);
  frame.pack();
  frame.setLocationRelativeTo(null);
  frame.setVisible(true);

  Thread.sleep(2000);

  textPane.setSelectionStart(4);
  textPane.setSelectionEnd(7);
  textPane.replaceSelection(" ");
}

Автор: JulT 29.9.2006, 12:16
сделала,ну и что теперь,кнопки пропали сами по себе,а мне ж нужно чтобы я сама их удалять могла smile 

Автор: LSD 29.9.2006, 12:19
Так ты вызывай replaceSelection() только для того диапазона где стоит нужная кнопка:
Код
public static void main(String[] args) throws Exception
{
  JButton button1 = new JButton("My button 1");
  JButton button2 = new JButton("My button 2");
  JTextPane textPane = new JTextPane();
  textPane.setText("Abcd  efg hij klmnop qrst uvw xyz");
  textPane.setCaretPosition(5);
  textPane.insertComponent(button1);
  textPane.setCaretPosition(9);
  textPane.insertComponent(button2);

  JFrame frame = new JFrame();
  frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
  frame.getContentPane().add(textPane);
  frame.pack();
  frame.setLocationRelativeTo(null);
  frame.setVisible(true);

  Thread.sleep(2000);

  textPane.setSelectionStart(5);
  textPane.setSelectionEnd(6);
  textPane.replaceSelection("");
}


Добавлено @ 12:22 
Я имел в виду в методе removeButton() вместо remove() вызывай replaceSelection(). Только для каждой кнопки придется помнить в какое место она вставлялась, для этого можно использовать например HashMap.

Автор: JulT 29.9.2006, 12:58
а что записывать в HashMap, в качестве ключа кнопку,а в качестве значения что,там же получается 2 значения,одно начало кнопки,второе конец

Автор: LSD 29.9.2006, 13:15
Создай класс для хранения позиции:
Код
public class ButtonPos
{
  public final String text;
  public final int start, end;

  public ButtonPos(String text, int start, int end)
  {
    if(text == null)
      text = "";
    this.text = text;
    this.start = start;
    this.end = end;
  }

  public boolean equals(Object o)
  {
    if(this == o)
      return true;
    if(o == null || getClass() != o.getClass())
      return false;

    final ButtonPos buttonPos = (ButtonPos) o;

    if(end != buttonPos.end)
      return false;
    if(start != buttonPos.start)
      return false;
    return text.equals(buttonPos.text);
  }

  public int hashCode()
  {
    int result = text.hashCode();
    result = 29 * result + start;
    result = 29 * result + end;
    return result;
  }
}

Автор: JulT 29.9.2006, 15:05
простите,а вы бы могли чуточку пояснить как работают эти 2 метода,в кратце хотя бы:
Код

 public boolean equals(Object o)
  {
    if(this == o)
      return true;
    if(o == null || getClass() != o.getClass())
      return false;

    final ButtonPos buttonPos = (ButtonPos) o;

    if(end != buttonPos.end)
      return false;
    if(start != buttonPos.start)
      return false;
    return text.equals(buttonPos.text);
  }

  public int hashCode()
  {
    int result = text.hashCode();
    result = 29 * result + start;
    result = 29 * result + end;
    return result;
  }
 smile 

Автор: LSD 29.9.2006, 15:43
equals()
1. Проверяем тот же это самый объект или нет (это не обязательно, но в большинстве случаев повышает производительность)
Код
if(this == o)
  return true;

2. Проверяем что объект не null и того типа что и данный:
Код
if(o == null || getClass() != o.getClass())
  return false;

3. Приводим переданый объект к типу ButtonPos и сравниваем каждое поле:
Код
final ButtonPos buttonPos = (ButtonPos) o;

if(end != buttonPos.end)
  return false;
if(start != buttonPos.start)
  return false;
return text.equals(buttonPos.text);


hashCode() - возвращает некоторое число характеризующее данный объект, что-то наподобие контрольной суммы объекта. Только назначение другое, используется в объектах наподобие HashMap. В данном случае считаем ее как зависимость от хеш кодов всех полей объекта.

Эти два метода в основном используются в коллекциях. Сравнение объектов в коллекциях происходит с помощью метода equals(). А hashCode() используется классами Hashtable, HashMap и т.д. Есть одно правило, если для двух разных объектов equals() возвращает true, то и hashCode() должен возвращать одинаковое число. Обратное не обязательно.

Автор: JulT 29.9.2006, 15:49
ой спасибо вам огромное за пояснения smile ,только у меня еще вопросик,сразу же извиняюсь за глупость smile  smile ,как мне его использовать этот класс, эти объекты ButtonPos,нужно ли их хранить где-то еще,типа ArrayList какой-то
сорри

Автор: LSD 29.9.2006, 16:03
Что-то наподобие такого:
Код
  private HashMap buttons = new HashMap();

  public void replaceText(JTextPane textPane)
  {
    ButtonPos pos = new ButtonPos(textPane.getSelectedText(), textPane.getSelectionStart(), textPane.getSelectionEnd());
    JButton button = new JButton(pos.text.trim());
    buttons.put(button, pos);
    textPane.insertComponent(button);
  }

  public void removeButton(JTextPane textPane, JButton button)
  {
    ButtonPos pos = (ButtonPos) buttons.get(button);
    textPane.setSelectionStart(pos.start);
    textPane.setSelectionEnd(pos.start + 1);
    textPane.replaceSelection(pos.text);
  }


Тут правда есть один момент: когда мы меняем текст, то положение кнопок меняется, и надо это как-то отслеживать. Пока я не знаю как это лучше сделать, но еще подумаю на эту тему.

Автор: JulT 29.9.2006, 16:40
спасибо огромное за помощь,не все получается при удалении кнопок,текст вставляется на место кнопки между другим словом,но об этом уже в понедельник,а то у меня уже сил нет.
Спасибо еще раз LSD smile 

Автор: LSD 29.9.2006, 16:43
Пожалуйста smile

Автор: LSD 1.10.2006, 15:38
Вообщем вот, что у меня получилось:
Код
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.HashMap;

public class TextFieldButton extends JFrame
{
  private JTextPane textPane;
  private HashMap buttonsMap;

  public TextFieldButton()
  {
    super("JTextField and JButton");

    buttonsMap = new HashMap();
    textPane = new JTextPane();
    String text = "abcdefghijklmnopqrstuvwxyz";
    textPane.setText(text);

    ActionListener listener = new RemoveButtonAction();
    for(int i = 0; i < textPane.getText().length() - 1; i += 3)
    {
      textPane.setSelectionStart(i);
      textPane.setSelectionEnd(i + 2);
      JButton button = new JButton("[" + textPane.getSelectedText().trim().toUpperCase() + "]");
      button.addActionListener(listener);
      buttonsMap.put(button, textPane.getSelectedText());
      textPane.insertComponent(button);
    }

    getContentPane().add(new JScrollPane(textPane));
  }

  public static void main(String[] args)
  {
    TextFieldButton t = new TextFieldButton();
    t.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    t.pack();
    t.setLocationRelativeTo(null);
    t.setVisible(true);
  }

  private class RemoveButtonAction implements ActionListener
  {
    public void actionPerformed(ActionEvent e)
    {
      JButton button = (JButton) e.getSource();
      Point point = SwingUtilities.convertPoint(button.getParent(), button.getLocation(), textPane);
      int start = textPane.viewToModel(point);
      String text = (String) buttonsMap.get(button);
      textPane.setSelectionStart(start);
      textPane.setSelectionEnd(start + 1);
      textPane.replaceSelection(text);
    }
  }
}

Автор: JulT 2.10.2006, 10:50
спасибо большое,но тут есть один моментик.дело в том,что при нажатии на кнопочку,у меня должно появлятся другое окошко,а в данном случае она(конпка) исчезает,мне нужно,чтобы кнопка исчезала тогда,когда мы нажимаем правой клавишей на ней,потом вылазит менюшка,в которой я выбираю пункт убрать кнопку,вот,как такое сделать smile 

Автор: LSD 2.10.2006, 11:30
Это совсем не сложно smile
Код
import java.awt.*;
import java.awt.event.*;
import java.util.HashMap;
import javax.swing.*;

@SuppressWarnings("unchecked")
public class TextFieldButton extends JFrame
{
  private JTextPane textPane;
  private HashMap buttonsMap;

  public TextFieldButton()
  {
    super("JTextField and JButton");

    buttonsMap = new HashMap();
    textPane = new JTextPane();
    String text = "abcdefghijklmnopqrstuvwxyz";
    textPane.setText(text);

    MouseListener listener = new MouseAdapter()
    {
      public void mouseClicked(MouseEvent e)
      {
        if(e.getButton() != MouseEvent.BUTTON3)
          return;
        JButton button = (JButton) e.getComponent();
        JPopupMenu popupMenu = getPopupMenu(button);
        popupMenu.show(button, e.getX() + 1, e.getY() + 1);
      }
    };
    for(int i = 0; i < textPane.getText().length() - 1; i += 3)
    {
      textPane.setSelectionStart(i);
      textPane.setSelectionEnd(i + 2);
      JButton button = new JButton("[" + textPane.getSelectedText().trim().toUpperCase() + "]");
      button.addMouseListener(listener);
      buttonsMap.put(button, textPane.getSelectedText());
      textPane.insertComponent(button);
    }

    getContentPane().add(new JScrollPane(textPane));
  }

  public static void main(String[] args)
  {
    TextFieldButton t = new TextFieldButton();
    t.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    t.pack();
    t.setLocationRelativeTo(null);
    t.setVisible(true);
  }

  private void removeButton(JButton button)
  {
    Point point = SwingUtilities.convertPoint(button.getParent(), button.getLocation(), textPane);
    int start = textPane.viewToModel(point);
    String text = (String) buttonsMap.get(button);
    textPane.setSelectionStart(start);
    textPane.setSelectionEnd(start + 1);
    textPane.replaceSelection(text);
  }

  private JPopupMenu getPopupMenu(JButton button)
  {
    JPopupMenu popupMenu = new JPopupMenu("Remove menu");
    popupMenu.add(new RemoveButtonAction(button));
    return popupMenu;
  }

  private class RemoveButtonAction extends AbstractAction
  {
    private JButton button;

    public RemoveButtonAction(JButton button)
    {
      super("Remove button");
      this.button = button;
    }

    public void actionPerformed(ActionEvent e)
    {
      removeButton(button);
    }
  }
}

Автор: JulT 2.10.2006, 11:43
спасибо ОГРОМНОЕ ВАМ smile ,УРАААААААА.
А теперь наверное наступает самое сложное: я разобрала предложение, в нем находятся кнопочки, теперь мне всю эту структуру нужно где-то хранить,не знаю где,или в базе данных,или может в файле каком-то.
Надо чтобы когда пользователь выбрал просмотр,ему сразу же в JTextPane вставлялось это разобранное предложение со всеми кнопками и событиями для этих кнопок.Это вообще реально сделать

Автор: JulT 2.10.2006, 13:59
поробую сама разобраться,если что спрошу

Автор: LSD 2.10.2006, 14:11
Для начала попробуй его просто сериализовывать (но есть у меня сильное подозрение, что так работать не будет).

Добавлено @ 14:12 
Да, и не забудь все свои листенеры сделать сериализуемыми.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)