Как передать событие методу?

Я бы пошел с GridLayout . GridLayout разделит вашу панель на ячейки в соответствии с заданными строками / столбцами (проверьте ее конструктор). Тогда каждый компонент будет соответствовать 100% (ширина и высота) для ячейки.

Однако: Если вы установите макет сетки на 1 строку и 4 столбца (ваш случай) и добавите только 1 компонент, макет будет настроен следующим образом: 1 строка и 1 столбец, потому что он выиграл т пустое место.

Уловка / Решение: Добавьте пустой компонент точно так же, как мы добавляем пробел в BoxLayout.

private static Component createSpace() {
    return Box.createRigidArea(new Dimension(1, 1));
}

Недостаток: Если вы хотите добавить компонент на панель после его отображения, вы должны удалить пробелы, чтобы вам пришлось либо сохранять все пустые компоненты в структуре, либо сделайте следующее (я всегда предпочитаю это):

gridLayoutPanel.removeAll();
gridLayoutPanel.add(component1);
gridLayoutPanel.add(newComponent); //This was space before
gridLayoutPanel.add(createSpace());
gridLayoutPanel.add(createSpace());
gridLayoutPanel.repaint();
gridLayoutPanel.revalidate();

SSCCE будет ( игнорировать высоту компонентов ):

import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class GridLayoutTest extends JFrame {
    public GridLayoutTest() {
        getContentPane().setLayout(new GridLayout(1, 4));
        JButton component1 = new JButton("Component1");
        JButton component2 = new JButton("Component2");
        JButton component3 = new JButton("Component3");
        add(component1); //25% of the width
        add(component2); //25% of the width
        add(component3); //25% of the width
        add(createSpace()); //25% of the width
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(500, 200);
        setLocationRelativeTo(null);
    }

    private static Component createSpace() {
        return Box.createRigidArea(new Dimension(1, 1));
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new GridLayoutTest().setVisible(true));
    }
}

24
задан Peter Mortensen 13 September 2013 в 17:22
поделиться

5 ответов

Мой первоначальный ответ был подходящим из класса, который определил событие, но вы ' С тех пор мы обновили свой вопрос, чтобы отразить, что вы хотите выполнить это вне определяющего класса, поэтому я это сделал.

Только класс, определяющий событие, может ссылаться на неявную переменную делегата, которую использует событие. За пределами этого класса у вас есть доступ только к методам add и remove через + = и - = . Это означает, что вы не можете делать то, о чем просите, напрямую. Однако можно использовать функциональный подход.

class A{
    public event EventHandler Event1;

    public void TriggerEvent1(){
        if(Event1 != null)
            Event1(this, EventArgs.Empty);
    }
}

class B{
    static void HandleEvent(object o, EventArgs e){
        Console.WriteLine("Woo-hoo!");
    }

    static void AttachToEvent(Action<EventHandler> attach){
        attach(HandleEvent);
    }

    static void Main(){
        A a = new A();
        AttachToEvent(handler=>a.Event1 += handler);
        a.TriggerEvent1();
    }
}
25
ответ дан 28 November 2019 в 23:49
поделиться
    delegate void doIt(object sender, object data);
    event doIt OnDoIt;

    void add(doIt theDel)
    {
        OnDoIt += theDel;
    }

    void doIt1(object a, object b)
    {
    }

    void doIt2(object a, object b)
    {
    }

    void add()
    {
        add(doIt1);
        add(doIt2);
    }
1
ответ дан thelost 28 November 2019 в 23:49
поделиться

Я сделал это так:

public AttachToHandleEvent(Object obj, string EventName)
{
    EventInfo mfi = obj.GetType().GetEvent(EventName);
    MethodInfo mobj = mfi.GetAddMethod();
    mobj.Invoke(obj, new object[] { Item_Click});
}

private void Item_Click(object sender, EventArgs e)
{
    MessageBox.Show("lalala");
}

ToolStripMenuItem tool = new ToolStripMenuItem();
AttachToHandleEvent(tool "Click");

Спасибо всем за советы. Это решение не могло быть сделано без вашей помощи.

6
ответ дан 28 November 2019 в 23:49
поделиться

Просто напишите tool.Click += Item_Click;

Edit: From MSDN "События могут быть вызваны только из класса или структуры, в которой они (события) объявлены". Поэтому то, что вы пытаетесь сделать, невозможно. Не могли бы вы подробнее рассказать о своих потребностях? Почему вы хотите передать событие в качестве параметра?

2
ответ дан 28 November 2019 в 23:49
поделиться

Это невозможно. Вы можете использовать делегата вместо события, если это соответствует вашим потребностям.

2
ответ дан 28 November 2019 в 23:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: